diff options
author | Jeremy Allison <jra@samba.org> | 2008-11-11 10:20:24 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2008-11-11 10:20:24 -0800 |
commit | 4f2635b729e636e123afacb0970c3d49343b3e90 (patch) | |
tree | 76d632982f23f08b23593af78614e9414dbbac2c | |
parent | 8cb23a6b2950d7419767845b6097470f76f348a7 (diff) | |
parent | 2e6bf03e519e180a1ee672dc9c9171d9e0cd114f (diff) | |
download | samba-4f2635b729e636e123afacb0970c3d49343b3e90.tar.gz samba-4f2635b729e636e123afacb0970c3d49343b3e90.tar.bz2 samba-4f2635b729e636e123afacb0970c3d49343b3e90.zip |
Merge branch 'master' of ssh://jra@git.samba.org/data/git/samba
339 files changed, 7985 insertions, 5812 deletions
diff --git a/docs-xml/smbdotconf/tuning/syncalways.xml b/docs-xml/smbdotconf/tuning/syncalways.xml index 5d8eb2d568..9a095d596b 100644 --- a/docs-xml/smbdotconf/tuning/syncalways.xml +++ b/docs-xml/smbdotconf/tuning/syncalways.xml @@ -12,7 +12,7 @@ </command> call to ensure the data is written to disk. Note that the <parameter moreinfo="none">strict sync</parameter> parameter must be set to <constant>yes</constant> in order for this parameter to have - any affect.</para> + any effect.</para> </description> <related>strict sync</related> diff --git a/lib/replace/README b/lib/replace/README index 2f3b37340f..26383bc89a 100644 --- a/lib/replace/README +++ b/lib/replace/README @@ -46,6 +46,8 @@ mkdtemp mkstemp (a secure one!) pread pwrite +chown +lchown getpass readline (the library) inet_ntoa @@ -64,6 +66,11 @@ getifaddrs freeifaddrs utime utimes +dup2 +link +readlink +symlink +realpath Types: bool diff --git a/lib/replace/libreplace.m4 b/lib/replace/libreplace.m4 index 6f1543863a..30d7017d0f 100644 --- a/lib/replace/libreplace.m4 +++ b/lib/replace/libreplace.m4 @@ -107,8 +107,8 @@ AC_CHECK_HEADERS(stropts.h) AC_CHECK_FUNCS(seteuid setresuid setegid setresgid chroot bzero strerror) AC_CHECK_FUNCS(vsyslog setlinebuf mktime ftruncate chsize rename) AC_CHECK_FUNCS(waitpid strlcpy strlcat initgroups memmove strdup) -AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp) -AC_CHECK_FUNCS(isatty) +AC_CHECK_FUNCS(pread pwrite strndup strcasestr strtok_r mkdtemp dup2) +AC_CHECK_FUNCS(isatty chown lchown link readlink symlink realpath) AC_HAVE_DECL(setresuid, [#include <unistd.h>]) AC_HAVE_DECL(setresgid, [#include <unistd.h>]) AC_HAVE_DECL(errno, [#include <errno.h>]) diff --git a/lib/replace/replace.c b/lib/replace/replace.c index 98d799b07e..78c688d50c 100644 --- a/lib/replace/replace.c +++ b/lib/replace/replace.c @@ -2,6 +2,7 @@ Unix SMB/CIFS implementation. replacement routines for broken systems Copyright (C) Andrew Tridgell 1992-1998 + Copyright (C) Jelmer Vernooij 2005-2008 ** NOTE! The following LGPL license applies to the replace ** library. This does NOT imply that all of Samba is released @@ -614,3 +615,63 @@ int rep_utimes(const char *filename, const struct timeval tv[2]) return utime(filename, &u); } #endif + +#ifndef HAVE_DUP2 +int rep_dup2(int oldfd, int newfd) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_CHOWN +/** +chown isn't used much but OS/2 doesn't have it +**/ +int rep_chown(const char *fname, uid_t uid, gid_t gid) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_LINK +int rep_link(const char *oldpath, const char *newpath) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_READLINK +int rep_readlink(const char *path, char *buf, size_t bufsiz) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_SYMLINK +int rep_symlink(const char *oldpath, const char *newpath) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_LCHOWN +int rep_lchown(const char *fname,uid_t uid,gid_t gid) +{ + errno = ENOSYS; + return -1; +} +#endif + +#ifndef HAVE_REALPATH +char *rep_realpath(const char *path, char *resolved_path) +{ + /* As realpath is not a system call we can't return ENOSYS. */ + errno = EINVAL; + return NULL; +} +#endif diff --git a/lib/replace/replace.h b/lib/replace/replace.h index a8164b642b..c3b0604a2c 100644 --- a/lib/replace/replace.h +++ b/lib/replace/replace.h @@ -4,7 +4,7 @@ macros to go along with the lib/replace/ portability layer code Copyright (C) Andrew Tridgell 2005 - Copyright (C) Jelmer Vernooij 2006 + Copyright (C) Jelmer Vernooij 2006-2008 Copyright (C) Jeremy Allison 2007. ** NOTE! The following LGPL license applies to the replace @@ -215,6 +215,49 @@ int rep_seteuid(uid_t); int rep_setegid(gid_t); #endif +#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL)) +/* stupid glibc */ +int setresuid(uid_t ruid, uid_t euid, uid_t suid); +#endif +#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL)) +int setresgid(gid_t rgid, gid_t egid, gid_t sgid); +#endif + +#ifndef HAVE_CHOWN +#define chown rep_chown +int rep_chown(const char *path, uid_t uid, gid_t gid); +#endif + +#ifndef HAVE_CHROOT +#define chroot rep_chroot +int rep_chroot(const char *dirname); +#endif + +#ifndef HAVE_LINK +#define link rep_link +int rep_link(const char *oldpath, const char *newpath); +#endif + +#ifndef HAVE_READLINK +#define readlink rep_readlink +ssize_t rep_readlink(const char *path, char *buf, size_t bufsize); +#endif + +#ifndef HAVE_SYMLINK +#define symlink rep_symlink +int rep_symlink(const char *oldpath, const char *newpath); +#endif + +#ifndef HAVE_REALPATH +#define realpath rep_realpath +char *rep_realpath(const char *path, char *resolved_path); +#endif + +#ifndef HAVE_LCHOWN +#define lchown rep_lchown +int rep_lchown(const char *fname,uid_t uid,gid_t gid); +#endif + #ifndef HAVE_SETLINEBUF #define setlinebuf rep_setlinebuf void rep_setlinebuf(FILE *); @@ -358,6 +401,11 @@ struct tm; char *rep_strptime(const char *buf, const char *format, struct tm *tm); #endif +#ifndef HAVE_DUP2 +#define dup2 rep_dup2 +int rep_dup2(int oldfd, int newfd); +#endif + /* Load header file for dynamic linking stuff */ #ifdef HAVE_DLFCN_H #include <dlfcn.h> diff --git a/lib/util/charset/charcnv.c b/lib/util/charset/charcnv.c index 9dd68f05ea..1f3b1ac846 100644 --- a/lib/util/charset/charcnv.c +++ b/lib/util/charset/charcnv.c @@ -155,71 +155,21 @@ static smb_iconv_t get_conv_handle(struct smb_iconv_convenience *ic, return ic->conv_handles[from][to]; } - /** * Convert string from one encoding to another, making error checking etc * + * @param mem_ctx Memory context + * @param cd Iconv handle * @param src pointer to source string (multibyte or singlebyte) * @param srclen length of the source string in bytes * @param dest pointer to destination string (multibyte or singlebyte) * @param destlen maximal length allowed for string * @returns the number of bytes occupied in the destination **/ -_PUBLIC_ ssize_t convert_string_convenience(struct smb_iconv_convenience *ic, - charset_t from, charset_t to, - void const *src, size_t srclen, - void *dest, size_t destlen) -{ - size_t i_len, o_len; - size_t retval; - const char* inbuf = (const char*)src; - char* outbuf = (char*)dest; - smb_iconv_t descriptor; - - if (srclen == (size_t)-1) - srclen = strlen(inbuf)+1; - - descriptor = get_conv_handle(ic, from, to); - - if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { - /* conversion not supported, use as is */ - size_t len = MIN(srclen,destlen); - memcpy(dest,src,len); - return len; - } - - i_len=srclen; - o_len=destlen; - retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); - if(retval==(size_t)-1) { - const char *reason; - switch(errno) { - case EINVAL: - reason="Incomplete multibyte sequence"; - return -1; - case E2BIG: - reason="No more room"; - if (from == CH_UNIX) { - DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen, - (const char *)src)); - } else { - DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", - charset_name(ic, from), charset_name(ic, to), - (int)srclen, (int)destlen)); - } - return -1; - case EILSEQ: - reason="Illegal multibyte sequence"; - return -1; - } - /* smb_panic(reason); */ - } - return destlen-o_len; -} - -_PUBLIC_ ssize_t convert_string_talloc_descriptor(TALLOC_CTX *ctx, smb_iconv_t descriptor, void const *src, size_t srclen, void **dest) +_PUBLIC_ ssize_t iconv_talloc(TALLOC_CTX *ctx, + smb_iconv_t cd, + void const *src, size_t srclen, + void **dest) { size_t i_len, o_len, destlen; size_t retval; @@ -247,7 +197,7 @@ convert: end */ i_len = srclen; o_len = destlen-2; - retval = smb_iconv(descriptor, + retval = smb_iconv(cd, &inbuf, &i_len, &outbuf, &o_len); if(retval == (size_t)-1) { @@ -275,9 +225,73 @@ convert: *dest = ob; return destlen; + } /** + * Convert string from one encoding to another, making error checking etc + * + * @param src pointer to source string (multibyte or singlebyte) + * @param srclen length of the source string in bytes + * @param dest pointer to destination string (multibyte or singlebyte) + * @param destlen maximal length allowed for string + * @returns the number of bytes occupied in the destination + **/ +_PUBLIC_ ssize_t convert_string_convenience(struct smb_iconv_convenience *ic, + charset_t from, charset_t to, + void const *src, size_t srclen, + void *dest, size_t destlen) +{ + size_t i_len, o_len; + size_t retval; + const char* inbuf = (const char*)src; + char* outbuf = (char*)dest; + smb_iconv_t descriptor; + + if (srclen == (size_t)-1) + srclen = strlen(inbuf)+1; + + descriptor = get_conv_handle(ic, from, to); + + if (descriptor == (smb_iconv_t)-1 || descriptor == (smb_iconv_t)0) { + /* conversion not supported, use as is */ + size_t len = MIN(srclen,destlen); + memcpy(dest,src,len); + return len; + } + + i_len=srclen; + o_len=destlen; + retval = smb_iconv(descriptor, &inbuf, &i_len, &outbuf, &o_len); + if(retval==(size_t)-1) { + const char *reason; + switch(errno) { + case EINVAL: + reason="Incomplete multibyte sequence"; + return -1; + case E2BIG: + reason="No more room"; + if (from == CH_UNIX) { + DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d - '%s'\n", + charset_name(ic, from), charset_name(ic, to), + (int)srclen, (int)destlen, + (const char *)src)); + } else { + DEBUG(0,("E2BIG: convert_string(%s,%s): srclen=%d destlen=%d\n", + charset_name(ic, from), charset_name(ic, to), + (int)srclen, (int)destlen)); + } + return -1; + case EILSEQ: + reason="Illegal multibyte sequence"; + return -1; + } + /* smb_panic(reason); */ + } + return destlen-o_len; +} + +/** * Convert between character sets, allocating a new buffer using talloc for the result. * * @param srclen length of source buffer. @@ -310,7 +324,7 @@ _PUBLIC_ ssize_t convert_string_talloc_convenience(TALLOC_CTX *ctx, return -1; } - return convert_string_talloc_descriptor(ctx, descriptor, src, srclen, dest); + return iconv_talloc(ctx, descriptor, src, srclen, dest); } /* diff --git a/lib/util/charset/charset.h b/lib/util/charset/charset.h index cace79f949..b69bef2d61 100644 --- a/lib/util/charset/charset.h +++ b/lib/util/charset/charset.h @@ -122,6 +122,11 @@ ssize_t convert_string(charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen); +ssize_t iconv_talloc(TALLOC_CTX *mem_ctx, + smb_iconv_t cd, + void const *src, size_t srclen, + void **dest); + extern struct smb_iconv_convenience *global_iconv_convenience; codepoint_t next_codepoint(const char *str, size_t *size); @@ -145,7 +150,6 @@ ssize_t convert_string_convenience(struct smb_iconv_convenience *ic, charset_t from, charset_t to, void const *src, size_t srclen, void *dest, size_t destlen); -ssize_t convert_string_talloc_descriptor(TALLOC_CTX *ctx, smb_iconv_t descriptor, void const *src, size_t srclen, void **dest); ssize_t convert_string_talloc_convenience(TALLOC_CTX *ctx, struct smb_iconv_convenience *ic, charset_t from, charset_t to, diff --git a/lib/util/config.mk b/lib/util/config.mk index 61e193b0c4..22f22b5771 100644 --- a/lib/util/config.mk +++ b/lib/util/config.mk @@ -34,10 +34,12 @@ PUBLIC_HEADERS += $(addprefix $(libutilsrcdir)/, util.h \ byteorder.h \ data_blob.h \ debug.h \ + memory.h \ mutex.h \ safe_string.h \ time.h \ util_ldb.h \ + talloc_stack.h \ xfile.h) [SUBSYSTEM::ASN1_UTIL] diff --git a/lib/util/debug.h b/lib/util/debug.h index 8c634f910a..a5962b04bb 100644 --- a/lib/util/debug.h +++ b/lib/util/debug.h @@ -17,6 +17,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _SAMBA_DEBUG_H_ +#define _SAMBA_DEBUG_H_ + /** * @file * @brief Debugging macros @@ -80,7 +83,7 @@ enum debug_logtype {DEBUG_STDOUT = 0, DEBUG_FILE = 1, DEBUG_STDERR = 2}; */ _PUBLIC_ void dbghdr(int level, const char *location, const char *func); -_PUBLIC_ void dbghdrclass(int level, int class, const char *location, const char *func); +_PUBLIC_ void dbghdrclass(int level, int cls, const char *location, const char *func); /** reopen the log file (usually called because the log file name might have changed) @@ -131,3 +134,5 @@ _PUBLIC_ void register_debug_handlers(const char *name, struct debug_ops *ops); _PUBLIC_ void dbgtext(const char *format, ...) PRINTF_ATTRIBUTE(1,2); extern XFILE *dbf; + +#endif diff --git a/lib/util/dprintf.c b/lib/util/dprintf.c index e4f02758eb..3e6d0e8bca 100644 --- a/lib/util/dprintf.c +++ b/lib/util/dprintf.c @@ -60,7 +60,7 @@ _PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) if (ret <= 0) return ret; - clen = convert_string_talloc_descriptor(NULL, display_cd, p, ret, (void **)&p2); + clen = iconv_talloc(NULL, display_cd, p, ret, (void **)&p2); if (clen == -1) { /* the string can't be converted - do the best we can, filling in non-printing chars with '?' */ diff --git a/lib/util/util.h b/lib/util/util.h index 6a341b218d..ec1cfef110 100644 --- a/lib/util/util.h +++ b/lib/util/util.h @@ -49,12 +49,26 @@ extern const char *panic_action; /** * assert macros */ +#ifdef DEVELOPER #define SMB_ASSERT(b) do { if (!(b)) { \ - DEBUG(0,("PANIC: assert failed at %s(%d)\n", __FILE__, __LINE__)); \ - smb_panic("assert failed"); }} while (0) + DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \ + __FILE__, __LINE__, #b)); smb_panic("assert failed: " #b); }} while(0) +#else +/* redefine the assert macro for non-developer builds */ +#define SMB_ASSERT(b) do { if (!(b)) { \ + DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \ + __FILE__, __LINE__, #b)); }} while (0) +#endif -#if defined(VALGRIND) +#if _SAMBA_BUILD_ == 4 +#ifdef VALGRIND #define strlen(x) valgrind_strlen(x) +size_t valgrind_strlen(const char *s); +#endif +#endif + +#ifndef ABS +#define ABS(a) ((a)>0?(a):(-(a))) #endif #include "../lib/util/memory.h" @@ -69,10 +83,12 @@ _PUBLIC_ void call_backtrace(void); **/ _PUBLIC_ _NORETURN_ void smb_panic(const char *why); +#if _SAMBA_BUILD_ == 4 /** setup our fault handlers **/ _PUBLIC_ void fault_setup(const char *pname); +#endif /** register a fault handler. @@ -168,12 +184,14 @@ _PUBLIC_ char *generate_random_str_list(TALLOC_CTX *mem_ctx, size_t len, const c _PUBLIC_ char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); /* The following definitions come from lib/util/dprintf.c */ +#if _SAMBA_BUILD_ == 4 _PUBLIC_ void d_set_iconv(smb_iconv_t); _PUBLIC_ int d_vfprintf(FILE *f, const char *format, va_list ap) PRINTF_ATTRIBUTE(2,0); _PUBLIC_ int d_fprintf(FILE *f, const char *format, ...) PRINTF_ATTRIBUTE(2,3); _PUBLIC_ int d_printf(const char *format, ...) PRINTF_ATTRIBUTE(1,2); _PUBLIC_ void display_set_stderr(void); +#endif /* The following definitions come from lib/util/util_str.c */ @@ -256,7 +274,6 @@ _PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, siz Unescape a URL encoded string, in place. **/ _PUBLIC_ void rfc1738_unescape(char *buf); -size_t valgrind_strlen(const char *s); /** format a string into length-prefixed dotted domain format, as used in NBT @@ -286,11 +303,6 @@ limited by 'n' bytes _PUBLIC_ size_t ascii_len_n(const char *src, size_t n); /** - Return a string representing a CIFS attribute for a file. -**/ -_PUBLIC_ char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib); - -/** Set a boolean variable from the text value stored in the passed string. Returns true in success, false if the passed string does not correctly represent a boolean. @@ -306,10 +318,12 @@ _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean); */ _PUBLIC_ bool conv_str_bool(const char * str, bool * val); +#if _SAMBA_BUILD_ == 4 /** * Convert a size specification like 16K into an integral number of bytes. **/ _PUBLIC_ bool conv_str_size(const char * str, uint64_t * val); +#endif /** * Parse a uint64_t value from a string @@ -354,7 +368,9 @@ _PUBLIC_ bool strequal(const char *s1, const char *s2); /* The following definitions come from lib/util/util_strlist.c */ /* separators for lists */ +#ifndef LIST_SEP #define LIST_SEP " \t,\n\r" +#endif /** build a null terminated list of strings from a input string and a @@ -642,6 +658,7 @@ _PUBLIC_ int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize); * @brief MS-style Filename matching */ +#if _SAMBA_BUILD_ == 4 /* protocol types. It assumes that higher protocols include lower protocols as subsets. FIXME: Move to one of the smb-specific headers */ enum protocol_types { @@ -658,6 +675,7 @@ int ms_fnmatch(const char *pattern, const char *string, enum protocol_types prot /** a generic fnmatch function - uses for non-CIFS pattern matching */ int gen_fnmatch(const char *pattern, const char *string); +#endif /* The following definitions come from lib/util/mutex.c */ @@ -707,10 +725,12 @@ _PUBLIC_ int idr_remove(struct idr_context *idp, int id); /* The following definitions come from lib/util/become_daemon.c */ +#if _SAMBA_BUILD_ == 4 /** Become a daemon, discarding the controlling terminal. **/ _PUBLIC_ void become_daemon(bool fork); +#endif /** * Load a ini-style file. diff --git a/lib/util/util_ldb.h b/lib/util/util_ldb.h index 43f98ae1a9..f9eb028916 100644 --- a/lib/util/util_ldb.h +++ b/lib/util/util_ldb.h @@ -1,6 +1,8 @@ #ifndef __LIB_UTIL_UTIL_LDB_H__ #define __LIB_UTIL_UTIL_LDB_H__ +struct ldb_dn; + /* The following definitions come from lib/util/util_ldb.c */ int gendb_search_v(struct ldb_context *ldb, diff --git a/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h index 4ef4e9d60d..e03352d7cf 100644 --- a/libcli/nbt/libnbt.h +++ b/libcli/nbt/libnbt.h @@ -122,6 +122,8 @@ struct nbt_name_socket { struct socket_address *); void *private_data; } unexpected; + + uint32_t wack_timeout; }; diff --git a/libcli/nbt/nbtsocket.c b/libcli/nbt/nbtsocket.c index dbbdc1b02a..65ed872533 100644 --- a/libcli/nbt/nbtsocket.c +++ b/libcli/nbt/nbtsocket.c @@ -247,7 +247,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req->received_wack = true; /* although there can be a timeout in the packet, w2k3 screws it up, so better to set it ourselves */ - req->timeout = lp_parm_int(global_loadparm, NULL, "nbt", "wack_timeout", 30); + req->timeout = nbtsock->wack_timeout; req->te = event_add_timed(req->nbtsock->event_ctx, req, timeval_current_ofs(req->timeout, 0), nbt_name_socket_timeout, req); @@ -334,6 +334,7 @@ _PUBLIC_ struct nbt_name_socket *nbt_name_socket_init(TALLOC_CTX *mem_ctx, nbtsock->send_queue = NULL; nbtsock->num_pending = 0; + nbtsock->wack_timeout = 30; nbtsock->incoming.handler = NULL; nbtsock->unexpected.handler = NULL; nbtsock->iconv_convenience = iconv_convenience; diff --git a/libcli/nbt/pynbt.c b/libcli/nbt/pynbt.c index 9179245e88..6750ad7b4e 100644 --- a/libcli/nbt/pynbt.c +++ b/libcli/nbt/pynbt.c @@ -48,7 +48,8 @@ static PyObject *py_nbt_node_init(PyTypeObject *self, PyObject *args, PyObject * return NULL; ev = s4_event_context_init(ret->mem_ctx); - ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, py_iconv_convenience(ret->mem_ctx)); + ret->socket = nbt_name_socket_init(ret->mem_ctx, ev, + py_iconv_convenience(ret->mem_ctx)); return (PyObject *)ret; } diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c index be33ba47e2..160e7bc3e0 100644 --- a/libcli/util/doserr.c +++ b/libcli/util/doserr.c @@ -37,6 +37,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_BAD_NET_RESP", WERR_BAD_NET_RESP }, { "WERR_UNEXP_NET_ERR", WERR_UNEXP_NET_ERR }, { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, + { "WERR_SEM_TIMEOUT", WERR_SEM_TIMEOUT }, { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, { "WERR_FILE_EXISTS", WERR_FILE_EXISTS }, { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, @@ -61,6 +62,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, + { "WERR_GROUP_NOT_FOUND", WERR_GROUP_NOT_FOUND }, + { "WERR_USER_NOT_FOUND", WERR_USER_NOT_FOUND }, { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, { "WERR_TIME_DIFF_AT_DC", WERR_TIME_DIFF_AT_DC }, @@ -68,6 +71,16 @@ static const struct werror_code_struct dos_errs[] = { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, + { "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED }, + { "WERR_USER_EXISTS", WERR_USER_EXISTS }, + { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, + { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, + { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, + { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, + { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, + { "WERR_GROUP_EXISTS", WERR_GROUP_EXISTS }, + { "WERR_MEMBER_IN_GROUP", WERR_MEMBER_IN_GROUP }, + { "WERR_USER_NOT_IN_GROUP", WERR_USER_NOT_IN_GROUP }, { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, { "WERR_STATUS_MORE_ENTRIES", WERR_STATUS_MORE_ENTRIES }, { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, @@ -85,6 +98,8 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, { "WERR_INVALID_COMPUTERNAME", WERR_INVALID_COMPUTERNAME }, { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, + { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, + { "WERR_DC_NOT_FOUND", WERR_DC_NOT_FOUND }, { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, { "WERR_NO_SUCH_PRIVILEGE", WERR_NO_SUCH_PRIVILEGE }, @@ -120,6 +135,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS }, { "WERR_NOT_FOUND", WERR_NOT_FOUND }, { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, + { "WERR_NO_TRUST_SAM_ACCOUNT", WERR_NO_TRUST_SAM_ACCOUNT }, { "WERR_CLASS_NOT_REGISTERED", WERR_CLASS_NOT_REGISTERED }, { "WERR_NO_SHUTDOWN_IN_PROGRESS", WERR_NO_SHUTDOWN_IN_PROGRESS }, { "WERR_SHUTDOWN_ALREADY_IN_PROGRESS", WERR_SHUTDOWN_ALREADY_IN_PROGRESS }, @@ -134,6 +150,24 @@ static const struct werror_code_struct dos_errs[] = { "WERR_RPC_E_REMOTE_DISABLED", WERR_RPC_E_REMOTE_DISABLED }, { "WERR_NOT_CONNECTED", WERR_NOT_CONNECTED }, { "WERR_NAME_NOT_FOUND", WERR_NAME_NOT_FOUND}, + { "WERR_NONE_MAPPED", WERR_NONE_MAPPED }, + { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, + { "WERR_SPECIAL_ACCOUNT", WERR_SPECIAL_ACCOUNT }, + { "WERR_ALIAS_EXISTS", WERR_ALIAS_EXISTS }, + { "WERR_NO_SUCH_ALIAS", WERR_NO_SUCH_ALIAS }, + { "WERR_MEMBER_IN_ALIAS", WERR_MEMBER_IN_ALIAS }, + { "WERR_TIME_SKEW", WERR_TIME_SKEW }, + { "WERR_IO_PENDING", WERR_IO_PENDING }, + { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, + { "WERR_SERVICE_ALREADY_RUNNING", WERR_SERVICE_ALREADY_RUNNING }, + { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, + { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, + { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, + { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE }, + { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, + { "WERR_SERVICE_NEVER_STARTED", WERR_SERVICE_NEVER_STARTED }, + { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, + { "WERR_ACCOUNT_LOCKED_OUT", WERR_ACCOUNT_LOCKED_OUT }, { NULL, W_ERROR(0) } }; @@ -161,3 +195,57 @@ const char *win_errstr(WERROR werror) return msg; } + +struct werror_str_struct { + WERROR werror; + const char *friendly_errstr; +}; + +const struct werror_str_struct dos_err_strs[] = { + { WERR_OK, "Success" }, + { WERR_ACCESS_DENIED, "Access is denied" }, + { WERR_INVALID_PARAM, "Invalid parameter" }, + { WERR_NOT_SUPPORTED, "Not supported" }, + { WERR_BAD_PASSWORD, "A bad password was supplied" }, + { WERR_NOMEM, "Out of memory" }, + { WERR_NO_LOGON_SERVERS, "No logon servers found" }, + { WERR_NO_SUCH_LOGON_SESSION, "No such logon session" }, + { WERR_DOMAIN_CONTROLLER_NOT_FOUND, "A domain controller could not be found" }, + { WERR_DC_NOT_FOUND, "A domain controller could not be found" }, + { WERR_SETUP_NOT_JOINED, "Join failed" }, + { WERR_SETUP_ALREADY_JOINED, "Machine is already joined" }, + { WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" }, + { WERR_LOGON_FAILURE, "Invalid logon credentials" }, + { WERR_USER_EXISTS, "User account already exists" }, + { WERR_PASSWORD_MUST_CHANGE, "The password must be changed" }, + { WERR_ACCOUNT_LOCKED_OUT, "Account locked out" }, + { WERR_TIME_SKEW, "Time difference between client and server" }, + { WERR_USER_ALREADY_EXISTS, "User already exists" }, + { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, + { WERR_NONE_MAPPED, "Could not map names to SIDs" }, + { WERR_NO_SUCH_USER, "No such User" }, + { WERR_GROUP_EXISTS, "Group already exists" }, + { WERR_DS_DRA_BAD_DN, "An invalid distinguished name was specified for this replication" }, + { WERR_DS_DRA_BAD_NC, "An invalid naming context was specified for this replication operation" }, + { WERR_WRONG_PASSWORD, "The current password is incorrect" } +}; + + + +/***************************************************************************** + Get friendly error string for WERRORs + *****************************************************************************/ + +const char *get_friendly_werror_msg(WERROR werror) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(dos_err_strs); i++) { + if (W_ERROR_V(dos_err_strs[i].werror) == + W_ERROR_V(werror)) { + return dos_err_strs[i].friendly_errstr; + } + } + + return win_errstr(werror); +} diff --git a/libcli/util/ntstatus.h b/libcli/util/ntstatus.h index bf03d51d02..139562d8c2 100644 --- a/libcli/util/ntstatus.h +++ b/libcli/util/ntstatus.h @@ -592,6 +592,7 @@ typedef uint32_t NTSTATUS; #define NT_STATUS_TOO_MANY_LINKS NT_STATUS(0xC0000000 | 0x0265) #define NT_STATUS_QUOTA_LIST_INCONSISTENT NT_STATUS(0xC0000000 | 0x0266) #define NT_STATUS_FILE_IS_OFFLINE NT_STATUS(0xC0000000 | 0x0267) +#define NT_STATUS_DS_BUSY NT_STATUS(0xC0000000 | 0x02a5) #define NT_STATUS_DS_NO_MORE_RIDS NT_STATUS(0xC0000000 | 0x02a8) #define NT_STATUS_NOT_A_REPARSE_POINT NT_STATUS(0xC0000000 | 0x0275) #define NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED NT_STATUS(0xC0000000 | 0x02E9) @@ -628,6 +629,9 @@ const char *get_nt_error_c_code(NTSTATUS nt_code); *****************************************************************************/ NTSTATUS nt_status_string_to_code(const char *nt_status_str); +/** Used by ntstatus_dos_equal: */ +extern bool ntstatus_check_dos_mapping; + #define NT_STATUS_IS_OK(x) (NT_STATUS_V(x) == 0) #define NT_STATUS_IS_ERR(x) ((NT_STATUS_V(x) & 0xc0000000) == 0xc0000000) /* checking for DOS error mapping here is ugly, but unfortunately the diff --git a/libcli/util/werror.h b/libcli/util/werror.h index 1ebd5cc349..0d99c7bb31 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -136,6 +136,7 @@ typedef uint32_t WERROR; #define WERR_TIME_SKEW W_ERROR(1398) #define WERR_EVENTLOG_FILE_CORRUPT W_ERROR(1500) #define WERR_SERVER_UNAVAILABLE W_ERROR(1722) +#define WERR_NO_TRUST_SAM_ACCOUNT W_ERROR(1787) #define WERR_INVALID_FORM_NAME W_ERROR(1902) #define WERR_INVALID_FORM_SIZE W_ERROR(1903) #define WERR_PASSWORD_MUST_CHANGE W_ERROR(1907) @@ -258,6 +259,7 @@ typedef uint32_t WERROR; *****************************************************************************/ const char *win_errstr(WERROR werror); +const char *get_friendly_werror_msg(WERROR werror); #endif diff --git a/librpc/idl/misc.idl b/librpc/idl/misc.idl index ff548fe804..1182ef1fc2 100644 --- a/librpc/idl/misc.idl +++ b/librpc/idl/misc.idl @@ -2,12 +2,15 @@ miscellaneous IDL structures */ +cpp_quote("#define netr_SamDatabaseID8Bit netr_SamDatabaseID") [ pointer_default(unique) ] interface misc { + typedef enum netr_SamDatabaseID8Bit netr_SamDatabaseID8Bit; + typedef [public,noprint,gensize,noejs] struct { uint32 time_low; uint16 time_mid; diff --git a/librpc/idl/named_pipe_auth.idl b/librpc/idl/named_pipe_auth.idl new file mode 100644 index 0000000000..7d85eba9eb --- /dev/null +++ b/librpc/idl/named_pipe_auth.idl @@ -0,0 +1,44 @@ +#include "idl_types.h" +/* + miscellaneous IDL structures +*/ + +import "netlogon.idl"; + +[ + pointer_default(unique) +] +interface named_pipe_auth +{ + const char *NAMED_PIPE_AUTH_MAGIC = "NPAM"; + + typedef [switch_type(uint32)] union { + [case(0)] ;/* anonymous */ + [case(1)] netr_SamInfo3 info1; + } named_pipe_auth_req_info; + + typedef [public,gensize] struct { + [flag(NDR_BIG_ENDIAN), + value(ndr_size_named_pipe_auth_req(r,ndr->flags)-4)] + uint32 length; + [charset(DOS),value(NAMED_PIPE_AUTH_MAGIC)] uint8 magic[4]; + uint32 level; + [switch_is(level)] named_pipe_auth_req_info info; + } named_pipe_auth_req; + + typedef [switch_type(uint32)] union { + [case(0)] ; + [case(1)] ; + } named_pipe_auth_rep_info; + + typedef [public,gensize] struct { + [flag(NDR_BIG_ENDIAN), + value(ndr_size_named_pipe_auth_rep(r,ndr->flags)-4)] + uint32 length; + [charset(DOS),value(NAMED_PIPE_AUTH_MAGIC)] uint8 magic[4]; + uint32 level; + [switch_is(level)] named_pipe_auth_rep_info info; + NTSTATUS status; + } named_pipe_auth_rep; +} + diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl index c89cf37ee7..e9b5170e9d 100644 --- a/librpc/idl/netlogon.idl +++ b/librpc/idl/netlogon.idl @@ -8,10 +8,13 @@ import "misc.idl", "lsa.idl", "samr.idl", "security.idl", "nbt.idl"; #include "idl_types.h" +cpp_quote("#define netr_DeltaEnum8Bit netr_DeltaEnum") + [ uuid("12345678-1234-abcd-ef00-01234567cffb"), version(1.0), endpoint("ncacn_np:[\\pipe\\netlogon]","ncacn_ip_tcp:","ncalrpc:"), + helper("../librpc/ndr/ndr_netlogon.h"), pointer_default(unique) ] @@ -19,6 +22,7 @@ interface netlogon { typedef bitmap samr_AcctFlags samr_AcctFlags; typedef bitmap samr_GroupAttrs samr_GroupAttrs; + typedef enum netr_DeltaEnum8Bit netr_DeltaEnum8Bit; /*****************/ /* Function 0x00 */ @@ -432,7 +436,7 @@ interface netlogon boolean8 lm_password_present; boolean8 password_expired; lsa_String comment; - lsa_String parameters; + lsa_BinaryString parameters; uint16 country_code; uint16 code_page; netr_USER_PRIVATE_INFO user_private_info; @@ -958,14 +962,38 @@ interface netlogon /* i'm not at all sure how this call works */ + typedef [bitmap16bit] bitmap { + NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED = 0x0001, + NETR_CHANGELOG_CHANGED_PASSWORD = 0x0002, + NETR_CHANGELOG_SID_INCLUDED = 0x0004, + NETR_CHANGELOG_NAME_INCLUDED = 0x0008, + NETR_CHANGELOG_FIRST_PROMOTION_OBJ = 0x0010 + } netr_ChangeLogFlags; + + typedef [nodiscriminant] union { + [case(NETR_CHANGELOG_SID_INCLUDED)] dom_sid object_sid; + [case(NETR_CHANGELOG_NAME_INCLUDED)] nstring object_name; + [default]; + } netr_ChangeLogObject; + + typedef [public,gensize] struct { + uint32 serial_number1; + uint32 serial_number2; + uint32 object_rid; + netr_ChangeLogFlags flags; + netr_SamDatabaseID8Bit db_index; + netr_DeltaEnum8Bit delta_type; + [switch_is(flags & (NETR_CHANGELOG_SID_INCLUDED|NETR_CHANGELOG_NAME_INCLUDED))] netr_ChangeLogObject object; + } netr_ChangeLogEntry; + NTSTATUS netr_DatabaseRedo( [in] [string,charset(UTF16)] uint16 logon_server[], [in] [string,charset(UTF16)] uint16 computername[], - [in] netr_Authenticator credential, + [in] netr_Authenticator *credential, [in,out,ref] netr_Authenticator *return_authenticator, - [in,unique][size_is(change_log_entry_size)] uint8 *change_log_entry, - [in] uint32 change_log_entry_size, - [out,ref] netr_DELTA_ENUM_ARRAY *delta_enum_array + [in] [subcontext(4),subcontext_size(change_log_entry_size)] netr_ChangeLogEntry change_log_entry, + [in] [value(ndr_size_netr_ChangeLogEntry(&change_log_entry, ndr->flags))] uint32 change_log_entry_size, + [out,ref] netr_DELTA_ENUM_ARRAY **delta_enum_array ); diff --git a/source3/librpc/idl/samr.idl b/librpc/idl/samr.idl index cd5fe07845..ee179407d4 100644 --- a/source3/librpc/idl/samr.idl +++ b/librpc/idl/samr.idl @@ -40,6 +40,8 @@ import "misc.idl", "lsa.idl", "security.idl"; ACB_NO_AUTH_DATA_REQD = 0x00080000 /* 1 = No authorization data required */ } samr_AcctFlags; + /* SAM server specific access rights */ + typedef [bitmap32bit] bitmap { SAMR_ACCESS_CONNECT_TO_SERVER = 0x00000001, SAMR_ACCESS_SHUTDOWN_SERVER = 0x00000002, @@ -49,6 +51,29 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_ACCESS_OPEN_DOMAIN = 0x00000020 } samr_ConnectAccessMask; + const int SAMR_ACCESS_ALL_ACCESS = 0x0000003F; + + const int GENERIC_RIGHTS_SAM_ALL_ACCESS = + (STANDARD_RIGHTS_REQUIRED_ACCESS | + SAMR_ACCESS_ALL_ACCESS); + + const int GENERIC_RIGHTS_SAM_READ = + (STANDARD_RIGHTS_READ_ACCESS | + SAMR_ACCESS_ENUM_DOMAINS); + + const int GENERIC_RIGHTS_SAM_WRITE = + (STANDARD_RIGHTS_WRITE_ACCESS | + SAMR_ACCESS_CREATE_DOMAIN | + SAMR_ACCESS_INITIALIZE_SERVER | + SAMR_ACCESS_SHUTDOWN_SERVER); + + const int GENERIC_RIGHTS_SAM_EXECUTE = + (STANDARD_RIGHTS_EXECUTE_ACCESS | + SAMR_ACCESS_OPEN_DOMAIN | + SAMR_ACCESS_CONNECT_TO_SERVER); + + /* User Object specific access rights */ + typedef [bitmap32bit] bitmap { SAMR_USER_ACCESS_GET_NAME_ETC = 0x00000001, SAMR_USER_ACCESS_GET_LOCALE = 0x00000002, @@ -63,6 +88,35 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP = 0x00000400 } samr_UserAccessMask; + const int SAMR_USER_ACCESS_ALL_ACCESS = 0x000007FF; + + const int GENERIC_RIGHTS_USER_ALL_ACCESS = + (STANDARD_RIGHTS_REQUIRED_ACCESS | + SAMR_USER_ACCESS_ALL_ACCESS); /* 0x000f07ff */ + + const int GENERIC_RIGHTS_USER_READ = + (STANDARD_RIGHTS_READ_ACCESS | + SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP | + SAMR_USER_ACCESS_GET_GROUPS | + SAMR_USER_ACCESS_GET_ATTRIBUTES | + SAMR_USER_ACCESS_GET_LOGONINFO | + SAMR_USER_ACCESS_GET_LOCALE); /* 0x0002031a */ + + const int GENERIC_RIGHTS_USER_WRITE = + (STANDARD_RIGHTS_WRITE_ACCESS | + SAMR_USER_ACCESS_CHANGE_PASSWORD | + SAMR_USER_ACCESS_SET_LOC_COM | + SAMR_USER_ACCESS_SET_ATTRIBUTES | + SAMR_USER_ACCESS_SET_PASSWORD | + SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP); /* 0x000204e4 */ + + const int GENERIC_RIGHTS_USER_EXECUTE = + (STANDARD_RIGHTS_EXECUTE_ACCESS | + SAMR_USER_ACCESS_CHANGE_PASSWORD | + SAMR_USER_ACCESS_GET_NAME_ETC); /* 0x00020041 */ + + /* Domain Object specific access rights */ + typedef [bitmap32bit] bitmap { SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 = 0x00000001, SAMR_DOMAIN_ACCESS_SET_INFO_1 = 0x00000002, @@ -77,6 +131,34 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_DOMAIN_ACCESS_SET_INFO_3 = 0x00000400 } samr_DomainAccessMask; + const int SAMR_DOMAIN_ACCESS_ALL_ACCESS = 0x000007FF; + + const int GENERIC_RIGHTS_DOMAIN_ALL_ACCESS = + (STANDARD_RIGHTS_REQUIRED_ACCESS | + SAMR_DOMAIN_ACCESS_ALL_ACCESS); + + const int GENERIC_RIGHTS_DOMAIN_READ = + (STANDARD_RIGHTS_READ_ACCESS | + SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS | + SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2); + + const int GENERIC_RIGHTS_DOMAIN_WRITE = + (STANDARD_RIGHTS_WRITE_ACCESS | + SAMR_DOMAIN_ACCESS_SET_INFO_3 | + SAMR_DOMAIN_ACCESS_CREATE_ALIAS | + SAMR_DOMAIN_ACCESS_CREATE_GROUP | + SAMR_DOMAIN_ACCESS_CREATE_USER | + SAMR_DOMAIN_ACCESS_SET_INFO_2 | + SAMR_DOMAIN_ACCESS_SET_INFO_1); + + const int GENERIC_RIGHTS_DOMAIN_EXECUTE = + (STANDARD_RIGHTS_EXECUTE_ACCESS | + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT | + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS | + SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1); + + /* Group Object specific access rights */ + typedef [bitmap32bit] bitmap { SAMR_GROUP_ACCESS_LOOKUP_INFO = 0x00000001, SAMR_GROUP_ACCESS_SET_INFO = 0x00000002, @@ -85,6 +167,28 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_GROUP_ACCESS_GET_MEMBERS = 0x00000010 } samr_GroupAccessMask; + const int SAMR_GROUP_ACCESS_ALL_ACCESS = 0x0000001F; + + const int GENERIC_RIGHTS_GROUP_ALL_ACCESS = + (STANDARD_RIGHTS_REQUIRED_ACCESS | + SAMR_GROUP_ACCESS_ALL_ACCESS); /* 0x000f001f */ + + const int GENERIC_RIGHTS_GROUP_READ = + (STANDARD_RIGHTS_READ_ACCESS | + SAMR_GROUP_ACCESS_GET_MEMBERS); /* 0x00020010 */ + + const int GENERIC_RIGHTS_GROUP_WRITE = + (STANDARD_RIGHTS_WRITE_ACCESS | + SAMR_GROUP_ACCESS_REMOVE_MEMBER | + SAMR_GROUP_ACCESS_ADD_MEMBER | + SAMR_GROUP_ACCESS_SET_INFO); /* 0x0002000e */ + + const int GENERIC_RIGHTS_GROUP_EXECUTE = + (STANDARD_RIGHTS_EXECUTE_ACCESS | + SAMR_GROUP_ACCESS_LOOKUP_INFO); /* 0x00020001 */ + + /* Alias Object specific access rights */ + typedef [bitmap32bit] bitmap { SAMR_ALIAS_ACCESS_ADD_MEMBER = 0x00000001, SAMR_ALIAS_ACCESS_REMOVE_MEMBER = 0x00000002, @@ -93,6 +197,26 @@ import "misc.idl", "lsa.idl", "security.idl"; SAMR_ALIAS_ACCESS_SET_INFO = 0x00000010 } samr_AliasAccessMask; + const int SAMR_ALIAS_ACCESS_ALL_ACCESS = 0x0000001F; + + const int GENERIC_RIGHTS_ALIAS_ALL_ACCESS = + (STANDARD_RIGHTS_REQUIRED_ACCESS | + SAMR_ALIAS_ACCESS_ALL_ACCESS); /* 0x000f001f */ + + const int GENERIC_RIGHTS_ALIAS_READ = + (STANDARD_RIGHTS_READ_ACCESS | + SAMR_ALIAS_ACCESS_GET_MEMBERS); /* 0x00020004 */ + + const int GENERIC_RIGHTS_ALIAS_WRITE = + (STANDARD_RIGHTS_WRITE_ACCESS | + SAMR_ALIAS_ACCESS_REMOVE_MEMBER | + SAMR_ALIAS_ACCESS_ADD_MEMBER | + SAMR_ALIAS_ACCESS_SET_INFO); /* 0x00020013 */ + + const int GENERIC_RIGHTS_ALIAS_EXECUTE = + (STANDARD_RIGHTS_EXECUTE_ACCESS | + SAMR_ALIAS_ACCESS_LOOKUP_INFO); /* 0x00020008 */ + /******************/ /* Function: 0x00 */ NTSTATUS samr_Connect ( @@ -293,7 +417,7 @@ import "misc.idl", "lsa.idl", "security.idl"; /************************/ /* Function 0x09 */ /* - only levels 1, 3, 4, 6, 7, 9, 12 are valid for this + only levels 1, 3, 4, 6, 7, 9, 12 are valid for this call in w2k3 */ NTSTATUS samr_SetDomainInfo( @@ -312,14 +436,10 @@ import "misc.idl", "lsa.idl", "security.idl"; [out,ref] policy_handle *group_handle, [out,ref] uint32 *rid ); - + /************************/ /* Function 0x0b */ - - const int MAX_SAM_ENTRIES_W2K = 0x400; /* 1024 */ - const int MAX_SAM_ENTRIES_W95 = 50; - NTSTATUS samr_EnumDomainGroups( [in] policy_handle *domain_handle, [in,out,ref] uint32 *resume_handle, @@ -729,7 +849,7 @@ import "misc.idl", "lsa.idl", "security.idl"; typedef struct { samr_AcctFlags acct_flags; } samr_UserInfo16; - + typedef struct { NTTIME acct_expiry; } samr_UserInfo17; @@ -1011,7 +1131,7 @@ import "misc.idl", "lsa.idl", "security.idl"; this seems to be an alphabetic search function. The returned index is the index for samr_QueryDisplayInfo needed to get names occurring after the specified name. The supplied name does not need to exist - in the database (for example you can supply just a first letter for + in the database (for example you can supply just a first letter for searching starting at that letter) The level corresponds to the samr_QueryDisplayInfo level @@ -1088,7 +1208,7 @@ import "misc.idl", "lsa.idl", "security.idl"; NTSTATUS samr_QueryUserInfo2( [in,ref] policy_handle *user_handle, [in] uint16 level, - [out,ref,switch_is(level)] samr_UserInfo *info + [out,ref,switch_is(level)] samr_UserInfo **info ); /************************/ @@ -1206,7 +1326,7 @@ import "misc.idl", "lsa.idl", "security.idl"; /************************/ /* Function 0x3a */ /* - seems to be an exact alias for samr_SetUserInfo() + seems to be an exact alias for samr_SetUserInfo() */ [public] NTSTATUS samr_SetUserInfo2( [in,ref] policy_handle *user_handle, @@ -1310,10 +1430,9 @@ import "misc.idl", "lsa.idl", "security.idl"; NTSTATUS samr_RidToSid( [in,ref] policy_handle *domain_handle, [in] uint32 rid, - [out,ref] dom_sid2 *sid + [out,ref] dom_sid2 **sid ); - /************************/ /* Function 0x42 */ @@ -1424,7 +1543,7 @@ import "misc.idl", "lsa.idl", "security.idl"; NTSTATUS samr_ValidatePassword( [in] samr_ValidatePasswordLevel level, - [in,switch_is(level)] samr_ValidatePasswordReq req, - [out,ref,switch_is(level)] samr_ValidatePasswordRep *rep + [in,switch_is(level)] samr_ValidatePasswordReq *req, + [out,ref,switch_is(level)] samr_ValidatePasswordRep **rep ); } diff --git a/librpc/idl/security.idl b/librpc/idl/security.idl index 6704e300a5..3f70e2c36e 100644 --- a/librpc/idl/security.idl +++ b/librpc/idl/security.idl @@ -5,27 +5,10 @@ */ import "misc.idl"; - -/* - use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really - just a dom sid, but with the sub_auths represented as a conformant - array. As with all in-structure conformant arrays, the array length - is placed before the start of the structure. That's what gives rise - to the extra num_auths elemenent. We don't want the Samba code to - have to bother with such esoteric NDR details, so its easier to just - define it as a dom_sid and use pidl magic to make it all work. It - just means you need to mark a sid as a "dom_sid2" in the IDL when you - know it is of the conformant array variety -*/ -cpp_quote("#define dom_sid2 dom_sid") - -/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ -cpp_quote("#define dom_sid28 dom_sid") - -/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */ -cpp_quote("#define dom_sid0 dom_sid") +import "dom_sid.idl"; [ + helper("librpc/gen_ndr/ndr_dom_sid.h"), pointer_default(unique) ] interface security @@ -136,6 +119,20 @@ interface security const int SEC_RIGHTS_DIR_EXECUTE = SEC_RIGHTS_FILE_EXECUTE; const int SEC_RIGHTS_DIR_ALL = SEC_RIGHTS_FILE_ALL; + /* combinations of standard masks. */ + const int STANDARD_RIGHTS_ALL_ACCESS = SEC_STD_ALL; /* 0x001f0000 */ + const int STANDARD_RIGHTS_MODIFY_ACCESS = SEC_STD_READ_CONTROL; /* 0x00020000 */ + const int STANDARD_RIGHTS_EXECUTE_ACCESS = SEC_STD_READ_CONTROL; /* 0x00020000 */ + const int STANDARD_RIGHTS_READ_ACCESS = SEC_STD_READ_CONTROL; /* 0x00020000 */ + const int STANDARD_RIGHTS_WRITE_ACCESS = + (SEC_STD_WRITE_OWNER | + SEC_STD_WRITE_DAC | + SEC_STD_DELETE); /* 0x000d0000 */ + const int STANDARD_RIGHTS_REQUIRED_ACCESS = + (SEC_STD_DELETE | + SEC_STD_READ_CONTROL | + SEC_STD_WRITE_DAC | + SEC_STD_WRITE_OWNER); /* 0x000f0000 */ /***************************************************************/ /* WELL KNOWN SIDS */ @@ -243,7 +240,7 @@ interface security } sec_privilege; - typedef [bitmap8bit] bitmap { + typedef [public,bitmap8bit] bitmap { SEC_ACE_FLAG_OBJECT_INHERIT = 0x01, SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02, SEC_ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04, @@ -254,7 +251,7 @@ interface security SEC_ACE_FLAG_FAILED_ACCESS = 0x80 } security_ace_flags; - typedef [enum8bit] enum { + typedef [public,enum8bit] enum { SEC_ACE_TYPE_ACCESS_ALLOWED = 0, SEC_ACE_TYPE_ACCESS_DENIED = 1, SEC_ACE_TYPE_SYSTEM_AUDIT = 2, @@ -291,7 +288,7 @@ interface security [switch_is(flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] security_ace_object_inherited_type inherited_type; } security_ace_object; - typedef [nodiscriminant] union { + typedef [public,nodiscriminant] union { [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] security_ace_object object; [case(SEC_ACE_TYPE_ACCESS_DENIED_OBJECT)] security_ace_object object; [case(SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT)] security_ace_object object; @@ -299,7 +296,7 @@ interface security [default]; } security_ace_object_ctr; - typedef [public,gensize,nosize] struct { + typedef [public,nopull,gensize,nosize] struct { security_ace_type type; /* SEC_ACE_TYPE_* */ security_ace_flags flags; /* SEC_ACE_FLAG_* */ [value(ndr_size_security_ace(r,ndr->flags))] uint16 size; diff --git a/librpc/ndr/ndr.c b/librpc/ndr/ndr.c index 2f1daeaeb5..12f95a9ceb 100644 --- a/librpc/ndr/ndr.c +++ b/librpc/ndr/ndr.c @@ -933,7 +933,7 @@ _PUBLIC_ size_t ndr_size_struct(const void *p, int flags, ndr_push_flags_fn_t pu /* avoid recursion */ if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0; - ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm)); + ndr = ndr_push_init_ctx(NULL, global_iconv_convenience); if (!ndr) return 0; ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE; status = push(ndr, NDR_SCALARS|NDR_BUFFERS, discard_const(p)); @@ -958,7 +958,7 @@ _PUBLIC_ size_t ndr_size_union(const void *p, int flags, uint32_t level, ndr_pus /* avoid recursion */ if (flags & LIBNDR_FLAG_NO_NDR_SIZE) return 0; - ndr = ndr_push_init_ctx(NULL, lp_iconv_convenience(global_loadparm)); + ndr = ndr_push_init_ctx(NULL, global_iconv_convenience); if (!ndr) return 0; ndr->flags |= flags | LIBNDR_FLAG_NO_NDR_SIZE; diff --git a/librpc/ndr/ndr_netlogon.c b/librpc/ndr/ndr_netlogon.c new file mode 100644 index 0000000000..61a88c7a47 --- /dev/null +++ b/librpc/ndr/ndr_netlogon.c @@ -0,0 +1,64 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling special netlogon types + + Copyright (C) Guenther Deschner 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_netlogon.h" +#include "librpc/gen_ndr/ndr_misc.h" + +_PUBLIC_ enum ndr_err_code ndr_push_netr_SamDatabaseID8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit r) +{ + if (r > 0xff) return NDR_ERR_BUFSIZE; + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_netr_SamDatabaseID8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_netr_SamDatabaseID8Bit(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID8Bit r) +{ + ndr_print_netr_SamDatabaseID(ndr, name, r); +} + +_PUBLIC_ enum ndr_err_code ndr_push_netr_DeltaEnum8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_DeltaEnum8Bit r) +{ + if (r > 0xff) return NDR_ERR_BUFSIZE; + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_netr_DeltaEnum8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_DeltaEnum8Bit *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_netr_DeltaEnum8Bit(struct ndr_print *ndr, const char *name, enum netr_DeltaEnum8Bit r) +{ + ndr_print_netr_DeltaEnum(ndr, name, r); +} diff --git a/librpc/ndr/ndr_netlogon.h b/librpc/ndr/ndr_netlogon.h new file mode 100644 index 0000000000..0e6bd6a410 --- /dev/null +++ b/librpc/ndr/ndr_netlogon.h @@ -0,0 +1,28 @@ +/* + Unix SMB/CIFS implementation. + + routines for marshalling/unmarshalling special netlogon types + + Copyright (C) Guenther Deschner 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +_PUBLIC_ enum ndr_err_code ndr_push_netr_SamDatabaseID8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit r); +_PUBLIC_ enum ndr_err_code ndr_pull_netr_SamDatabaseID8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_SamDatabaseID8Bit *r); +_PUBLIC_ void ndr_print_netr_SamDatabaseID8Bit(struct ndr_print *ndr, const char *name, enum netr_SamDatabaseID8Bit r); + +_PUBLIC_ enum ndr_err_code ndr_push_netr_DeltaEnum8Bit(struct ndr_push *ndr, int ndr_flags, enum netr_DeltaEnum8Bit r); +_PUBLIC_ enum ndr_err_code ndr_pull_netr_DeltaEnum8Bit(struct ndr_pull *ndr, int ndr_flags, enum netr_DeltaEnum8Bit *r); +_PUBLIC_ void ndr_print_netr_DeltaEnum8Bit(struct ndr_print *ndr, const char *name, enum netr_DeltaEnum8Bit r); diff --git a/librpc/ndr/ndr_sec_helper.c b/librpc/ndr/ndr_sec_helper.c new file mode 100644 index 0000000000..4b135505d8 --- /dev/null +++ b/librpc/ndr/ndr_sec_helper.c @@ -0,0 +1,118 @@ +/* + Unix SMB/CIFS implementation. + + fast routines for getting the wire size of security objects + + Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan Metzmacher 2006-2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + + +#include "includes.h" +#include "librpc/gen_ndr/ndr_security.h" + +/* + return the wire size of a security_ace +*/ +size_t ndr_size_security_ace(const struct security_ace *ace, int flags) +{ + size_t ret; + + if (!ace) return 0; + + ret = 8 + ndr_size_dom_sid(&ace->trustee, flags); + + switch (ace->type) { + case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: + case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: + case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: + case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: + ret += 4; /* uint32 bitmap ace->object.object.flags */ + if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) { + ret += 16; /* GUID ace->object.object.type.type */ + } + if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { + ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */ + } + break; + default: + break; + } + + return ret; +} + +enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r) +{ + if (ndr_flags & NDR_SCALARS) { + uint32_t start_ofs = ndr->offset; + uint32_t size = 0; + uint32_t pad = 0; + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type)); + NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type)); + NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee)); + size = ndr->offset - start_ofs; + if (r->size < size) { + return ndr_pull_error(ndr, NDR_ERR_BUFSIZE, + "ndr_pull_security_ace: r->size %u < size %u", + (unsigned)r->size, size); + } + pad = r->size - size; + NDR_PULL_NEED_BYTES(ndr, pad); + ndr->offset += pad; + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object)); + } + return NDR_ERR_SUCCESS; +} + +/* + return the wire size of a security_acl +*/ +size_t ndr_size_security_acl(const struct security_acl *acl, int flags) +{ + size_t ret; + int i; + if (!acl) return 0; + ret = 8; + for (i=0;i<acl->num_aces;i++) { + ret += ndr_size_security_ace(&acl->aces[i], flags); + } + return ret; +} + +/* + return the wire size of a security descriptor +*/ +size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags) +{ + size_t ret; + if (!sd) return 0; + + ret = 20; + ret += ndr_size_dom_sid(sd->owner_sid, flags); + ret += ndr_size_dom_sid(sd->group_sid, flags); + ret += ndr_size_security_acl(sd->dacl, flags); + ret += ndr_size_security_acl(sd->sacl, flags); + return ret; +} + diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm index e30102b4e1..bb0c18e13c 100644 --- a/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm +++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Server.pm @@ -120,7 +120,8 @@ static NTSTATUS $name\__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_C /* unravel the NDR for the packet */ ndr_err = ndr_table_$name.calls[opnum].ndr_pull(pull, NDR_IN, *r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - dcerpc_log_packet(&ndr_table_$name, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_$name, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); dce_call->fault_code = DCERPC_FAULT_NDR; return NT_STATUS_NET_WRITE_FAULT; @@ -144,7 +145,8 @@ pidl " } if (dce_call->fault_code != 0) { - dcerpc_log_packet(&ndr_table_$name, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_$name, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); return NT_STATUS_NET_WRITE_FAULT; } @@ -167,7 +169,8 @@ pidl " } if (dce_call->fault_code != 0) { - dcerpc_log_packet(&ndr_table_$name, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_$name, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); return NT_STATUS_NET_WRITE_FAULT; } diff --git a/pidl/lib/Parse/Pidl/Samba4/Python.pm b/pidl/lib/Parse/Pidl/Samba4/Python.pm index 58e6910d3d..a3107d4672 100644 --- a/pidl/lib/Parse/Pidl/Samba4/Python.pm +++ b/pidl/lib/Parse/Pidl/Samba4/Python.pm @@ -698,6 +698,14 @@ sub Interface($$$) $self->pidl("}"); $self->pidl(""); + $self->pidl("status = dcerpc_init(lp_ctx);"); + $self->pidl("if (!NT_STATUS_IS_OK(status)) {"); + $self->indent; + $self->pidl("PyErr_SetNTSTATUS(status);"); + $self->pidl("return NULL;"); + $self->deindent; + $self->pidl("}"); + $self->pidl("credentials = cli_credentials_from_py_object(py_credentials);"); $self->pidl("if (credentials == NULL) {"); $self->indent; @@ -1173,7 +1181,6 @@ sub Parse($$$$$) $self->pidl("{"); $self->indent; $self->pidl("PyObject *m;"); - $self->pidl("NTSTATUS status;"); $self->pidl(""); foreach (@{$self->{ready_types}}) { @@ -1210,14 +1217,6 @@ sub Parse($$$$$) } $self->pidl(""); - $self->pidl("status = dcerpc_init();"); - $self->pidl("if (!NT_STATUS_IS_OK(status)) {"); - $self->indent; - $self->pidl("PyErr_SetNTSTATUS(status);"); - $self->pidl("return;"); - $self->deindent; - $self->pidl("}"); - $self->deindent; $self->pidl("}"); return ($self->{res_hdr}, $self->{res}); diff --git a/source3/Makefile.in b/source3/Makefile.in index c737b32468..c048e193a6 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -224,6 +224,8 @@ MODULES = $(VFS_MODULES) $(PDB_MODULES) $(RPC_MODULES) $(IDMAP_MODULES) \ $(CHARSET_MODULES) $(AUTH_MODULES) $(NSS_INFO_MODULES) \ $(GPEXT_MODULES) +EXTRA_ALL_TARGETS = @EXTRA_ALL_TARGETS@ + ###################################################################### # object file lists ###################################################################### @@ -267,7 +269,7 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \ ../librpc/ndr/ndr_misc.o \ librpc/gen_ndr/ndr_misc.o \ librpc/gen_ndr/ndr_security.o \ - librpc/ndr/ndr_sec_helper.o \ + ../librpc/ndr/ndr_sec_helper.o \ librpc/ndr/ndr_string.o \ librpc/ndr/sid.o \ ../librpc/ndr/uuid.o \ @@ -278,7 +280,8 @@ RPCCLIENT_NDR_OBJ = rpc_client/ndr.o LIBNDR_GEN_OBJ0 = librpc/gen_ndr/ndr_samr.o \ librpc/gen_ndr/ndr_lsa.o -LIBNDR_GEN_OBJ1 = librpc/gen_ndr/ndr_netlogon.o +LIBNDR_GEN_OBJ1 = librpc/gen_ndr/ndr_netlogon.o \ + ../librpc/ndr/ndr_netlogon.o LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \ $(LIBNDR_GEN_OBJ0) \ @@ -293,6 +296,7 @@ LIBNDR_GEN_OBJ = librpc/gen_ndr/ndr_wkssvc.o \ librpc/gen_ndr/ndr_notify.o \ librpc/gen_ndr/ndr_xattr.o \ librpc/gen_ndr/ndr_epmapper.o \ + librpc/gen_ndr/ndr_named_pipe_auth.o \ librpc/gen_ndr/ndr_ntsvcs.o RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o @@ -404,7 +408,7 @@ LIBNMB_OBJ = libsmb/unexpected.o libsmb/namecache.o libsmb/nmblib.o \ libsmb/namequery.o libsmb/conncache.o libads/dns.o NTERR_OBJ = libsmb/nterr.o -DOSERR_OBJ = libsmb/doserr.o +DOSERR_OBJ = ../libcli/util/doserr.o ERRORMAP_OBJ = libsmb/errormap.o DCE_RPC_ERR_OBJ = ../librpc/rpc/dcerpc_error.o @@ -639,6 +643,7 @@ VFS_FILEID_OBJ = modules/vfs_fileid.o VFS_AIO_FORK_OBJ = modules/vfs_aio_fork.o VFS_SYNCOPS_OBJ = modules/vfs_syncops.o VFS_ACL_XATTR_OBJ = modules/vfs_acl_xattr.o +VFS_ACL_TDB_OBJ = modules/vfs_acl_tdb.o VFS_SMB_TRAFFIC_ANALYZER_OBJ = modules/vfs_smb_traffic_analyzer.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -903,9 +908,9 @@ CUPS_OBJ = client/smbspool.o $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) $(POPT_LIB_OBJ) \ $(LIBNDR_GEN_OBJ0) -CIFS_MOUNT_OBJ = client/mount.cifs.o +CIFS_MOUNT_OBJ = client/mount.cifs.o client/mtab.o -CIFS_UMOUNT_OBJ = client/umount.cifs.o +CIFS_UMOUNT_OBJ = client/umount.cifs.o client/mtab.o CIFS_UPCALL_OBJ = client/cifs.upcall.o @@ -1156,7 +1161,8 @@ RPC_OPEN_TCP_OBJ = torture/rpc_open_tcp.o \ # now the rules... ###################################################################### all:: SHOWFLAGS basics libs $(SBIN_PROGS) $(BIN_PROGS) $(ROOT_SBIN_PROGS) \ - $(MODULES) $(NSS_MODULES) $(PAM_MODULES) @EXTRA_ALL_TARGETS@ + $(MODULES) $(NSS_MODULES) $(PAM_MODULES) @CIFSUPCALL_PROGS@ \ + $(EXTRA_ALL_TARGETS) basics:: @@ -1219,10 +1225,11 @@ samba3-idl:: ../librpc/idl/initshutdown.idl ../librpc/idl/srvsvc.idl ../librpc/idl/svcctl.idl \ ../librpc/idl/eventlog.idl ../librpc/idl/wkssvc.idl ../librpc/idl/netlogon.idl \ ../librpc/idl/notify.idl ../librpc/idl/epmapper.idl librpc/idl/messaging.idl \ - ../librpc/idl/xattr.idl ../librpc/idl/misc.idl librpc/idl/samr.idl \ + ../librpc/idl/xattr.idl ../librpc/idl/misc.idl ../librpc/idl/samr.idl \ ../librpc/idl/security.idl ../librpc/idl/dssetup.idl ../librpc/idl/krb5pac.idl \ ../librpc/idl/ntsvcs.idl librpc/idl/libnetapi.idl ../librpc/idl/drsuapi.idl \ - ../librpc/idl/drsblobs.idl ../librpc/idl/nbt.idl + ../librpc/idl/drsblobs.idl ../librpc/idl/nbt.idl \ + ../librpc/idl/named_pipe_auth.idl librpc/idl/dom_sid.idl librpc/gen_ndr/tables.c:: librpc/gen_ndr/*.h @echo "Generating $@" @@ -2453,6 +2460,10 @@ bin/smb_traffic_analyzer.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_SMB_TRAFFIC_ANALYZE @echo "Building plugin $@" @$(SHLD_MODULE) $(VFS_SMB_TRAFFIC_ANALYZER_OBJ) +bin/acl_tdb.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_ACL_TDB_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_ACL_TDB_OBJ) + bin/registry.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/registry.o @echo "Building plugin $@" @$(SHLD_MODULE) libgpo/gpext/registry.o @@ -2847,9 +2858,10 @@ valgrindtest:: all torture timelimit PERL="$(PERL)" $(srcdir)/script/tests/selftest.sh ${selftest_prefix} all "${smbtorture4_path}" SELFTEST_FORMAT = plain +selftestdir = ../selftest selftest:: all torture timelimit - @../selftest/selftest.pl --prefix=st --target=samba3 \ + @$(selftestdir)/selftest.pl --prefix=st --target=samba3 \ --testlist="$(srcdir)/selftest/tests.sh|" \ --expected-failures=$(srcdir)/selftest/knownfail \ --exclude=$(srcdir)/selftest/skip \ diff --git a/source3/auth/auth.c b/source3/auth/auth.c index 7f95656bef..505098c76a 100644 --- a/source3/auth/auth.c +++ b/source3/auth/auth.c @@ -469,13 +469,13 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) { case SEC_DOMAIN: DEBUG(5,("Making default auth method list for security=domain\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest sam winbind:ntdomain", NULL); break; case SEC_SERVER: DEBUG(5,("Making default auth method list for security=server\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest sam smbserver", NULL); break; @@ -483,36 +483,36 @@ NTSTATUS make_auth_context_subsystem(struct auth_context **auth_context) if (lp_encrypted_passwords()) { if ((lp_server_role() == ROLE_DOMAIN_PDC) || (lp_server_role() == ROLE_DOMAIN_BDC)) { DEBUG(5,("Making default auth method list for DC, security=user, encrypt passwords = yes\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest sam winbind:trustdomain", NULL); } else { DEBUG(5,("Making default auth method list for standalone security=user, encrypt passwords = yes\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest sam", NULL); } } else { DEBUG(5,("Making default auth method list for security=user, encrypt passwords = no\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest unix", NULL); } break; case SEC_SHARE: if (lp_encrypted_passwords()) { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = yes\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest sam", NULL); } else { DEBUG(5,("Making default auth method list for security=share, encrypt passwords = no\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest unix", NULL); } break; case SEC_ADS: DEBUG(5,("Making default auth method list for security=ADS\n")); - auth_method_list = str_list_make( + auth_method_list = str_list_make_v3( talloc_tos(), "guest sam winbind:ntdomain", NULL); break; diff --git a/source3/auth/token_util.c b/source3/auth/token_util.c index e739fdaabe..6c00aa0943 100644 --- a/source3/auth/token_util.c +++ b/source3/auth/token_util.c @@ -102,7 +102,7 @@ NT_USER_TOKEN *get_root_nt_token( void ) uid_to_sid(&u_sid, pw->pw_uid); gid_to_sid(&g_sid, pw->pw_gid); - token = create_local_nt_token(NULL, &u_sid, False, + token = create_local_nt_token(talloc_autofree_context(), &u_sid, False, 1, &global_sid_Builtin_Administrators); token->privileges = se_disk_operators; diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 2a9c2b7304..da2f98bff8 100644 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -39,9 +39,10 @@ #include <mntent.h> #include <fcntl.h> #include <limits.h> +#include "mount.h" #define MOUNT_CIFS_VERSION_MAJOR "1" -#define MOUNT_CIFS_VERSION_MINOR "11" +#define MOUNT_CIFS_VERSION_MINOR "12" #ifndef MOUNT_CIFS_VENDOR_SUFFIX #ifdef _SAMBA_BUILD_ @@ -79,15 +80,6 @@ #define MOUNT_PASSWD_SIZE 64 #define DOMAIN_SIZE 64 -/* exit status - bits below are ORed */ -#define EX_USAGE 1 /* incorrect invocation or permission */ -#define EX_SYSERR 2 /* out of memory, cannot fork, ... */ -#define EX_SOFTWARE 4 /* internal mount bug or wrong version */ -#define EX_USER 8 /* user interrupt */ -#define EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */ -#define EX_FAIL 32 /* mount failure */ -#define EX_SOMEOK 64 /* some mount succeeded */ - const char *thisprogram; int verboseflag = 0; static int got_password = 0; @@ -1424,48 +1416,57 @@ mount_retry: printf("Refer to the mount.cifs(8) manual page (e.g.man mount.cifs)\n"); rc = EX_FAIL; } else { + atexit(unlock_mtab); + rc = lock_mtab(); + if (rc) { + printf("cannot lock mtab"); + goto mount_exit; + } pmntfile = setmntent(MOUNTED, "a+"); - if(pmntfile) { - mountent.mnt_fsname = dev_name; - mountent.mnt_dir = mountpoint; - mountent.mnt_type = CONST_DISCARD(char *,"cifs"); - mountent.mnt_opts = (char *)malloc(220); - if(mountent.mnt_opts) { - char * mount_user = getusername(); - memset(mountent.mnt_opts,0,200); - if(flags & MS_RDONLY) - strlcat(mountent.mnt_opts,"ro",220); - else - strlcat(mountent.mnt_opts,"rw",220); - if(flags & MS_MANDLOCK) - strlcat(mountent.mnt_opts,",mand",220); - if(flags & MS_NOEXEC) - strlcat(mountent.mnt_opts,",noexec",220); - if(flags & MS_NOSUID) - strlcat(mountent.mnt_opts,",nosuid",220); - if(flags & MS_NODEV) - strlcat(mountent.mnt_opts,",nodev",220); - if(flags & MS_SYNCHRONOUS) - strlcat(mountent.mnt_opts,",synch",220); - if(mount_user) { - if(getuid() != 0) { - strlcat(mountent.mnt_opts,",user=",220); - strlcat(mountent.mnt_opts,mount_user,220); - } - /* free(mount_user); do not free static mem */ - } - } - mountent.mnt_freq = 0; - mountent.mnt_passno = 0; - rc = addmntent(pmntfile,&mountent); - endmntent(pmntfile); - SAFE_FREE(mountent.mnt_opts); - if (rc) - rc = EX_FILEIO; - } else { + if (!pmntfile) { printf("could not update mount table\n"); + unlock_mtab(); rc = EX_FILEIO; + goto mount_exit; } + mountent.mnt_fsname = dev_name; + mountent.mnt_dir = mountpoint; + mountent.mnt_type = CONST_DISCARD(char *,"cifs"); + mountent.mnt_opts = (char *)malloc(220); + if(mountent.mnt_opts) { + char * mount_user = getusername(); + memset(mountent.mnt_opts,0,200); + if(flags & MS_RDONLY) + strlcat(mountent.mnt_opts,"ro",220); + else + strlcat(mountent.mnt_opts,"rw",220); + if(flags & MS_MANDLOCK) + strlcat(mountent.mnt_opts,",mand",220); + if(flags & MS_NOEXEC) + strlcat(mountent.mnt_opts,",noexec",220); + if(flags & MS_NOSUID) + strlcat(mountent.mnt_opts,",nosuid",220); + if(flags & MS_NODEV) + strlcat(mountent.mnt_opts,",nodev",220); + if(flags & MS_SYNCHRONOUS) + strlcat(mountent.mnt_opts,",sync",220); + if(mount_user) { + if(getuid() != 0) { + strlcat(mountent.mnt_opts, + ",user=", 220); + strlcat(mountent.mnt_opts, + mount_user, 220); + } + } + } + mountent.mnt_freq = 0; + mountent.mnt_passno = 0; + rc = addmntent(pmntfile,&mountent); + endmntent(pmntfile); + unlock_mtab(); + SAFE_FREE(mountent.mnt_opts); + if (rc) + rc = EX_FILEIO; } mount_exit: if(mountpassword) { diff --git a/source3/client/mount.h b/source3/client/mount.h new file mode 100644 index 0000000000..23ea4f0cbd --- /dev/null +++ b/source3/client/mount.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008 Jeff Layton (jlayton@samba.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/* most of this info was taken from the util-linux-ng sources */ + +#ifndef _MOUNT_H_ +#define _MOUNT_H_ + +/* exit status - bits below are ORed */ +#define EX_USAGE 1 /* incorrect invocation or permission */ +#define EX_SYSERR 2 /* out of memory, cannot fork, ... */ +#define EX_SOFTWARE 4 /* internal mount bug or wrong version */ +#define EX_USER 8 /* user interrupt */ +#define EX_FILEIO 16 /* problems writing, locking, ... mtab/fstab */ +#define EX_FAIL 32 /* mount failure */ +#define EX_SOMEOK 64 /* some mount succeeded */ + +#define _PATH_MOUNTED_LOCK _PATH_MOUNTED "~" +#define _PATH_MOUNTED_TMP _PATH_MOUNTED ".tmp" + +extern int lock_mtab(void); +extern void unlock_mtab(void); + +#endif /* ! _MOUNT_H_ */ diff --git a/source3/client/mtab.c b/source3/client/mtab.c new file mode 100644 index 0000000000..93fbd11359 --- /dev/null +++ b/source3/client/mtab.c @@ -0,0 +1,219 @@ +/* + * mtab locking routines for use with mount.cifs and umount.cifs + * Copyright (C) 2008 Jeff Layton (jlayton@samba.org) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +/* + * This code was copied from the util-linux-ng sources and modified: + * + * git://git.kernel.org/pub/scm/utils/util-linux-ng/util-linux-ng.git + * + * ...specifically from mount/fstab.c. That file has no explicit license. The + * "default" license for anything in that tree is apparently GPLv2+, so I + * believe we're OK to copy it here. + * + * Jeff Layton <jlayton@samba.org> + */ + +#include <unistd.h> +#include <errno.h> +#include <stdio.h> +#include <sys/time.h> +#include <time.h> +#include <fcntl.h> +#include <mntent.h> +#include <stdlib.h> +#include <signal.h> +#include "mount.h" + + +/* Updating mtab ----------------------------------------------*/ + +/* Flag for already existing lock file. */ +static int we_created_lockfile = 0; +static int lockfile_fd = -1; + +/* Flag to indicate that signals have been set up. */ +static int signals_have_been_setup = 0; + +static void +handler (int sig) { + exit(EX_USER); +} + +static void +setlkw_timeout (int sig) { + /* nothing, fcntl will fail anyway */ +} + +/* Remove lock file. */ +void +unlock_mtab (void) { + if (we_created_lockfile) { + close(lockfile_fd); + lockfile_fd = -1; + unlink (_PATH_MOUNTED_LOCK); + we_created_lockfile = 0; + } +} + +/* Create the lock file. + The lock file will be removed if we catch a signal or when we exit. */ +/* The old code here used flock on a lock file /etc/mtab~ and deleted + this lock file afterwards. However, as rgooch remarks, that has a + race: a second mount may be waiting on the lock and proceed as + soon as the lock file is deleted by the first mount, and immediately + afterwards a third mount comes, creates a new /etc/mtab~, applies + flock to that, and also proceeds, so that the second and third mount + now both are scribbling in /etc/mtab. + The new code uses a link() instead of a creat(), where we proceed + only if it was us that created the lock, and hence we always have + to delete the lock afterwards. Now the use of flock() is in principle + superfluous, but avoids an arbitrary sleep(). */ + +/* Where does the link point to? Obvious choices are mtab and mtab~~. + HJLu points out that the latter leads to races. Right now we use + mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */ +#define MOUNTLOCK_LINKTARGET _PATH_MOUNTED_LOCK "%d" +#define MOUNTLOCK_LINKTARGET_LTH (sizeof(_PATH_MOUNTED_LOCK)+20) + +/* + * The original mount locking code has used sleep(1) between attempts and + * maximal number of attemps has been 5. + * + * There was very small number of attempts and extremely long waiting (1s) + * that is useless on machines with large number of concurret mount processes. + * + * Now we wait few thousand microseconds between attempts and we have global + * time limit (30s) rather than limit for number of attempts. The advantage + * is that this method also counts time which we spend in fcntl(F_SETLKW) and + * number of attempts is not so much restricted. + * + * -- kzak@redhat.com [2007-Mar-2007] + */ + +/* maximum seconds between first and last attempt */ +#define MOUNTLOCK_MAXTIME 30 + +/* sleep time (in microseconds, max=999999) between attempts */ +#define MOUNTLOCK_WAITTIME 5000 + +int +lock_mtab (void) { + int i; + struct timespec waittime; + struct timeval maxtime; + char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; + + if (!signals_have_been_setup) { + int sig = 0; + struct sigaction sa; + + sa.sa_handler = handler; + sa.sa_flags = 0; + sigfillset (&sa.sa_mask); + + while (sigismember (&sa.sa_mask, ++sig) != -1 + && sig != SIGCHLD) { + if (sig == SIGALRM) + sa.sa_handler = setlkw_timeout; + else + sa.sa_handler = handler; + sigaction (sig, &sa, (struct sigaction *) 0); + } + signals_have_been_setup = 1; + } + + sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ()); + + i = open (linktargetfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); + if (i < 0) { + /* linktargetfile does not exist (as a file) + and we cannot create it. Read-only filesystem? + Too many files open in the system? + Filesystem full? */ + return EX_FILEIO; + } + close(i); + + gettimeofday(&maxtime, NULL); + maxtime.tv_sec += MOUNTLOCK_MAXTIME; + + waittime.tv_sec = 0; + waittime.tv_nsec = (1000 * MOUNTLOCK_WAITTIME); + + /* Repeat until it was us who made the link */ + while (!we_created_lockfile) { + struct timeval now; + struct flock flock; + int errsv, j; + + j = link(linktargetfile, _PATH_MOUNTED_LOCK); + errsv = errno; + + if (j == 0) + we_created_lockfile = 1; + + if (j < 0 && errsv != EEXIST) { + (void) unlink(linktargetfile); + return EX_FILEIO; + } + + lockfile_fd = open (_PATH_MOUNTED_LOCK, O_WRONLY); + + if (lockfile_fd < 0) { + /* Strange... Maybe the file was just deleted? */ + gettimeofday(&now, NULL); + if (errno == ENOENT && now.tv_sec < maxtime.tv_sec) { + we_created_lockfile = 0; + continue; + } + (void) unlink(linktargetfile); + return EX_FILEIO; + } + + flock.l_type = F_WRLCK; + flock.l_whence = SEEK_SET; + flock.l_start = 0; + flock.l_len = 0; + + if (j == 0) { + /* We made the link. Now claim the lock. If we can't + * get it, continue anyway + */ + fcntl (lockfile_fd, F_SETLK, &flock); + (void) unlink(linktargetfile); + } else { + /* Someone else made the link. Wait. */ + gettimeofday(&now, NULL); + if (now.tv_sec < maxtime.tv_sec) { + alarm(maxtime.tv_sec - now.tv_sec); + if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) { + (void) unlink(linktargetfile); + return EX_FILEIO; + } + alarm(0); + nanosleep(&waittime, NULL); + } else { + (void) unlink(linktargetfile); + return EX_FILEIO; + } + close(lockfile_fd); + } + } + return 0; +} + diff --git a/source3/client/umount.cifs.c b/source3/client/umount.cifs.c index 3e2415ad00..aff7cea397 100644 --- a/source3/client/umount.cifs.c +++ b/source3/client/umount.cifs.c @@ -33,9 +33,10 @@ #include <errno.h> #include <string.h> #include <mntent.h> +#include "mount.h" #define UNMOUNT_CIFS_VERSION_MAJOR "0" -#define UNMOUNT_CIFS_VERSION_MINOR "5" +#define UNMOUNT_CIFS_VERSION_MINOR "6" #ifndef UNMOUNT_CIFS_VENDOR_SUFFIX #ifdef _SAMBA_BUILD_ @@ -137,24 +138,6 @@ static int umount_check_perm(char * dir) return rc; } -static int lock_mtab(void) -{ - int rc; - - rc = mknod(MOUNTED_LOCK , 0600, 0); - if(rc == -1) - printf("\ngetting lock file %s failed with %s\n",MOUNTED_LOCK, - strerror(errno)); - - return rc; - -} - -static void unlock_mtab(void) -{ - unlink(MOUNTED_LOCK); -} - static int remove_from_mtab(char * mountpoint) { int rc; @@ -168,6 +151,7 @@ static int remove_from_mtab(char * mountpoint) /* Do we first need to check if it is writable? */ + atexit(unlock_mtab); if (lock_mtab()) { printf("Mount table locked\n"); return -EACCES; diff --git a/source3/configure.in b/source3/configure.in index a59fe32aff..5e3eac55e2 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -399,7 +399,7 @@ dnl These have to be built static: default_static_modules="pdb_smbpasswd pdb_tdbsam rpc_lsarpc rpc_samr rpc_winreg rpc_initshutdown rpc_dssetup rpc_wkssvc rpc_svcctl2 rpc_ntsvcs2 rpc_netlogon rpc_netdfs rpc_srvsvc rpc_spoolss rpc_eventlog2 auth_sam auth_unix auth_winbind auth_server auth_domain auth_builtin auth_netlogond vfs_default nss_info_template" dnl These are preferably build shared, and static if dlopen() is not available -default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_acl_xattr vfs_smb_traffic_analyzer" +default_shared_modules="vfs_recycle vfs_audit vfs_extd_audit vfs_full_audit vfs_netatalk vfs_fake_perms vfs_default_quota vfs_readonly vfs_cap vfs_expand_msdfs vfs_shadow_copy vfs_shadow_copy2 charset_CP850 charset_CP437 auth_script vfs_readahead vfs_xattr_tdb vfs_streams_xattr vfs_acl_xattr vfs_acl_tdb vfs_smb_traffic_analyzer" if test "x$developer" = xyes; then default_static_modules="$default_static_modules rpc_rpcecho" @@ -857,19 +857,6 @@ if test x"$ac_cv_func_dirfd" = x"yes"; then default_shared_modules="$default_shared_modules vfs_syncops" fi -AC_CACHE_CHECK([for sig_atomic_t type],samba_cv_sig_atomic_t, [ - AC_TRY_COMPILE([ -#include <sys/types.h> -#if STDC_HEADERS -#include <stdlib.h> -#include <stddef.h> -#endif -#include <signal.h>],[sig_atomic_t i = 0], - samba_cv_sig_atomic_t=yes,samba_cv_sig_atomic_t=no)]) -if test x"$samba_cv_sig_atomic_t" = x"yes"; then - AC_DEFINE(HAVE_SIG_ATOMIC_T_TYPE,1,[Whether we have the atomic_t variable type]) -fi - AC_CACHE_CHECK([for struct sigevent type],samba_cv_struct_sigevent, [ AC_TRY_COMPILE([ #include <sys/types.h> @@ -908,11 +895,6 @@ if test x"$samba_cv_struct_timespec" = x"yes"; then AC_DEFINE(HAVE_STRUCT_TIMESPEC,1,[Whether we have struct timespec]) fi -# stupid headers have the functions but no declaration. grrrr. -AC_HAVE_DECL(errno, [#include <errno.h>]) -AC_HAVE_DECL(setresuid, [#include <unistd.h>]) -AC_HAVE_DECL(setresgid, [#include <unistd.h>]) - # and glibc has setresuid under linux but the function does # nothing until kernel 2.1.44! very dumb. AC_CACHE_CHECK([for real setresuid],samba_cv_have_setresuid,[ @@ -1025,20 +1007,20 @@ if test x"$ac_cv_func_execl" = x"no"; then EXTRA_BIN_PROGS="$EXTRA_BIN_PROGS bin/smbrun\$(EXEEXT)" fi -AC_CHECK_FUNCS(waitpid getcwd strdup strndup strnlen strerror chown fchown lchown chmod fchmod chroot link mknod mknod64) -AC_CHECK_FUNCS(strtol strtoll strtoul strtoull strtouq __strtoull) +AC_CHECK_FUNCS(getcwd fchown chmod fchmod mknod mknod64) +AC_CHECK_FUNCS(strtol) AC_CHECK_FUNCS(fstat strchr chflags) -AC_CHECK_FUNCS(getrlimit fsync fdatasync memset strlcpy strlcat setpgid) -AC_CHECK_FUNCS(memmove setsid glob strpbrk pipe crypt16 getauthuid) -AC_CHECK_FUNCS(strftime sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent) -AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf realpath) -AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf mktime rename ftruncate chsize stat64 fstat64) -AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt dup2 lseek64 ftruncate64) -AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam setlinebuf) +AC_CHECK_FUNCS(getrlimit fsync fdatasync setpgid) +AC_CHECK_FUNCS(setsid glob strpbrk crypt16 getauthuid) +AC_CHECK_FUNCS(sigprocmask sigblock sigaction sigset innetgr setnetgrent getnetgrent endnetgrent) +AC_CHECK_FUNCS(initgroups select poll rdchk getgrnam getgrent pathconf) +AC_CHECK_FUNCS(setpriv setgidx setuidx setgroups sysconf stat64 fstat64) +AC_CHECK_FUNCS(lstat64 fopen64 atexit grantpt lseek64 ftruncate64) +AC_CHECK_FUNCS(fseek64 fseeko64 ftell64 ftello64 setluid getpwanam) AC_CHECK_FUNCS(opendir64 readdir64 seekdir64 telldir64 rewinddir64 closedir64) AC_CHECK_FUNCS(getpwent_r) -AC_CHECK_FUNCS(getdents getdents64) -AC_CHECK_FUNCS(srandom random srand rand setenv usleep strcasecmp fcvt fcvtl symlink readlink) +AC_CHECK_FUNCS(getdents64) +AC_CHECK_FUNCS(setenv strcasecmp fcvt fcvtl) AC_CHECK_FUNCS(syslog vsyslog timegm) AC_CHECK_FUNCS(setlocale nl_langinfo) AC_CHECK_FUNCS(nanosleep) @@ -1046,7 +1028,7 @@ AC_CHECK_FUNCS(mlock munlock mlockall munlockall) AC_CHECK_FUNCS(memalign posix_memalign hstrerror) AC_CHECK_HEADERS(sys/mman.h) # setbuffer, shmget, shm_open are needed for smbtorture -AC_CHECK_FUNCS(setbuffer shmget shm_open) +AC_CHECK_FUNCS(shmget shm_open) # Find a method of generating a stack trace AC_CHECK_HEADERS(execinfo.h libexc.h libunwind.h) @@ -6105,6 +6087,7 @@ SMB_MODULE(vfs_syncops, \$(VFS_SYNCOPS_OBJ), "bin/syncops.$SHLIBEXT", VFS) SMB_MODULE(vfs_zfsacl, \$(VFS_ZFSACL_OBJ), "bin/zfsacl.$SHLIBEXT", VFS) SMB_MODULE(vfs_notify_fam, \$(VFS_NOTIFY_FAM_OBJ), "bin/notify_fam.$SHLIBEXT", VFS) SMB_MODULE(vfs_acl_xattr, \$(VFS_ACL_XATTR_OBJ), "bin/acl_xattr.$SHLIBEXT", VFS) +SMB_MODULE(vfs_acl_tdb, \$(VFS_ACL_TDB_OBJ), "bin/acl_tdb.$SHLIBEXT", VFS) SMB_MODULE(vfs_smb_traffic_analyzer, \$(VFS_SMB_TRAFFIC_ANALYZER_OBJ), "bin/smb_traffic_analyzer.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) diff --git a/source3/groupdb/mapping_ldb.c b/source3/groupdb/mapping_ldb.c index 1a6b99fa18..db3215552f 100644 --- a/source3/groupdb/mapping_ldb.c +++ b/source3/groupdb/mapping_ldb.c @@ -574,6 +574,13 @@ static int upgrade_map_record(TDB_CONTEXT *tdb_ctx, TDB_DATA key, return -1; } + if ((int)map.gid == -1) { + /* + * Ignore old invalid mappings + */ + return 0; + } + if (!add_mapping_entry(&map, 0)) { DEBUG(0,("Failed to add mapping entry during upgrade\n")); *(int *)state = -1; diff --git a/source3/include/includes.h b/source3/include/includes.h index 24e33c1720..4399c734d0 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -524,14 +524,6 @@ struct timespec { }; #endif -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - #ifdef HAVE_BROKEN_GETGROUPS #define GID_T int #else @@ -567,11 +559,12 @@ typedef char fstring[FSTRING_LEN]; #endif /* Samba 3 doesn't use iconv_convenience: */ -extern void *global_loadparm; +extern void *global_iconv_convenience; extern void *cmdline_lp_ctx; struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); /* Lists, trees, caching, database... */ +#include "../lib/util/util.h" #include "../lib/util/xfile.h" #include "../lib/util/memory.h" #include "../lib/util/attr.h" @@ -619,6 +612,7 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "msdfs.h" #include "rap.h" #include "../lib/crypto/md5.h" +#include "../lib/crypto/md4.h" #include "../lib/crypto/arcfour.h" #include "../lib/crypto/crc32.h" #include "../lib/crypto/hmacmd5.h" @@ -717,7 +711,7 @@ enum flush_reason_enum { #include "modules/nfs4_acls.h" #include "nsswitch/libwbclient/wbclient.h" -/***** automatically generated prototypes *****/ +/***** prototypes *****/ #ifndef NO_PROTO_H #include "proto.h" #endif @@ -810,14 +804,6 @@ enum flush_reason_enum { #define ULTRIX_AUTH 1 #endif -#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESUID_DECL)) -/* stupid glibc */ -int setresuid(uid_t ruid, uid_t euid, uid_t suid); -#endif -#if (defined(USE_SETRESUID) && !defined(HAVE_SETRESGID_DECL)) -int setresgid(gid_t rgid, gid_t egid, gid_t sgid); -#endif - /* yuck, I'd like a better way of doing this */ #define DIRP_SIZE (256 + 32) @@ -890,11 +876,6 @@ int smb_xvasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE( int asprintf_strupper_m(char **strp, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); char *talloc_asprintf_strupper_m(TALLOC_CTX *t, const char *fmt, ...) PRINTF_ATTRIBUTE(2,3); -/* we used to use these fns, but now we have good replacements - for snprintf and vsnprintf */ -#define slprintf snprintf -#define vslprintf vsnprintf - /* * Veritas File System. Often in addition to native. * Quotas different. diff --git a/source3/include/proto.h b/source3/include/proto.h index c6609be5d6..5f9203a21f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -542,7 +542,6 @@ int cancel_named_event(struct event_context *event_ctx, void dump_event_list(struct event_context *event_ctx); /* The following definitions come from lib/fault.c */ - void fault_setup(void (*fn)(void *)); void dump_core_setup(const char *progname); @@ -555,10 +554,6 @@ const char *file_id_string_tos(const struct file_id *id); void push_file_id_16(char *buf, const struct file_id *id); void pull_file_id_16(char *buf, struct file_id *id); -/* The following definitions come from lib/fsusage.c */ - -int sys_fsusage(const char *path, uint64_t *dfree, uint64_t *dsize); - /* The following definitions come from lib/gencache.c */ bool gencache_init(void); @@ -573,13 +568,6 @@ void gencache_iterate(void (*fn)(const char* key, const char *value, time_t time int gencache_lock_entry( const char *key ); void gencache_unlock_entry( const char *key ); -/* The following definitions come from lib/genrand.c */ - -void set_rand_reseed_callback(void (*fn)(void *, int *), void *userdata); -void set_need_random_reseed(void); -void generate_random_buffer(uint8_t *out, int len); -char *generate_random_str(TALLOC_CTX *mem_ctx, size_t len); - /* The following definitions come from lib/iconv.c */ NTSTATUS smb_register_charset(struct charset_functions *funcs) ; @@ -619,10 +607,6 @@ void init_ldap_debugging(void); char *escape_ldap_string_alloc(const char *s); char *escape_rdn_val_string_alloc(const char *s); -/* The following definitions come from lib/md4.c */ - -void mdfour(unsigned char *out, const unsigned char *in, int n); - /* The following definitions come from lib/module.c */ NTSTATUS smb_load_module(const char *module_name); @@ -796,13 +780,6 @@ bool share_access_check(const NT_USER_TOKEN *token, const char *sharename, uint32 desired_access); bool parse_usershare_acl(TALLOC_CTX *ctx, const char *acl_str, SEC_DESC **ppsd); -/* The following definitions come from lib/signal.c */ - -void BlockSignals(bool block,int signum); -void (*CatchSignal(int signum,void (*handler)(int )))(int); -void CatchChild(void); -void CatchChildLeaveStatus(void); - /* The following definitions come from lib/smbldap.c */ int smb_ldap_start_tls(LDAP *ldap_struct, int version); @@ -976,18 +953,11 @@ int no_acl_syscall_error(int err); int sys_get_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); int sys_set_quota(const char *path, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); -/* The following definitions come from lib/sysquotas_4A.c */ +/* The following definitions come from lib/sysquotas_*.c */ int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); -/* The following definitions come from lib/sysquotas_linux.c */ - -int sys_get_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); -int sys_set_vfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); - -/* The following definitions come from lib/sysquotas_xfs.c */ - int sys_get_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); int sys_set_xfs_quota(const char *path, const char *bdev, enum SMB_QUOTA_TYPE qtype, unid_t id, SMB_DISK_QUOTA *dp); @@ -1023,15 +993,8 @@ long sys_telldir(SMB_STRUCT_DIR *dirp); void sys_rewinddir(SMB_STRUCT_DIR *dirp); int sys_closedir(SMB_STRUCT_DIR *dirp); int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev); -char *sys_realpath(const char *path, char *resolved_path); int sys_waitpid(pid_t pid,int *status,int options); char *sys_getwd(char *s); -int sys_symlink(const char *oldpath, const char *newpath); -int sys_readlink(const char *path, char *buf, size_t bufsiz); -int sys_link(const char *oldpath, const char *newpath); -int sys_chown(const char *fname,uid_t uid,gid_t gid); -int sys_lchown(const char *fname,uid_t uid,gid_t gid); -int sys_chroot(const char *dname); void set_effective_capability(enum smbd_capability capability); void drop_effective_capability(enum smbd_capability capability); long sys_random(void); @@ -1050,11 +1013,6 @@ pid_t sys_fork(void); pid_t sys_getpid(void); int sys_popen(const char *command); int sys_pclose(int fd); -void *sys_dlopen(const char *name, int flags); -void *sys_dlsym(void *handle, const char *symbol); -int sys_dlclose (void *handle); -const char *sys_dlerror(void); -int sys_dup2(int oldfd, int newfd) ; ssize_t sys_getxattr (const char *path, const char *name, void *value, size_t size); ssize_t sys_lgetxattr (const char *path, const char *name, void *value, size_t size); ssize_t sys_fgetxattr (int filedes, const char *name, void *value, size_t size); @@ -1105,45 +1063,14 @@ void register_msg_pool_usage(struct messaging_context *msg_ctx); /* The following definitions come from lib/time.c */ -time_t get_time_t_max(void); -void GetTimeOfDay(struct timeval *tval); -time_t nt_time_to_unix(NTTIME nt); -void unix_to_nt_time(NTTIME *nt, time_t t); -bool null_time(time_t t); -bool null_nttime(NTTIME t); -bool null_timespec(struct timespec ts); void push_dos_date(uint8_t *buf, int offset, time_t unixdate, int zone_offset); void push_dos_date2(uint8_t *buf,int offset,time_t unixdate, int zone_offset); void push_dos_date3(uint8_t *buf,int offset,time_t unixdate, int zone_offset); time_t pull_dos_date(const uint8_t *date_ptr, int zone_offset); time_t pull_dos_date2(const uint8_t *date_ptr, int zone_offset); time_t pull_dos_date3(const uint8_t *date_ptr, int zone_offset); -char *timestring(TALLOC_CTX *mem_ctx, time_t t); -const char *nt_time_string(TALLOC_CTX *mem_ctx, NTTIME nt); -NTTIME nttime_from_string(const char *s); -struct timeval timeval_zero(void); -bool timeval_is_zero(const struct timeval *tv); -struct timeval timeval_current(void); -struct timeval timeval_set(uint32_t secs, uint32_t usecs); -struct timeval timeval_add(const struct timeval *tv, - uint32_t secs, uint32_t usecs); -struct timeval timeval_sum(const struct timeval *tv1, - const struct timeval *tv2); -struct timeval timeval_current_ofs(uint32_t secs, uint32_t usecs); -int timeval_compare(const struct timeval *tv1, const struct timeval *tv2); -bool timeval_expired(const struct timeval *tv); -double timeval_elapsed2(const struct timeval *tv1, const struct timeval *tv2); -double timeval_elapsed(const struct timeval *tv); -struct timeval timeval_min(const struct timeval *tv1, - const struct timeval *tv2); -struct timeval timeval_max(const struct timeval *tv1, - const struct timeval *tv2); -struct timeval timeval_until(const struct timeval *tv1, - const struct timeval *tv2); -NTTIME timeval_to_nttime(const struct timeval *tv); uint32 convert_time_t_to_uint32(time_t t); time_t convert_uint32_to_time_t(uint32 u); -int get_time_zone(time_t t); bool nt_time_is_zero(const NTTIME *nt); time_t generalized_to_unix_time(const char *str); int get_server_zone_offset(void); @@ -1180,7 +1107,6 @@ void cli_put_dos_date3(struct cli_state *cli, char *buf, int offset, time_t unix time_t cli_make_unix_date(struct cli_state *cli, const void *date_ptr); time_t cli_make_unix_date2(struct cli_state *cli, const void *date_ptr); time_t cli_make_unix_date3(struct cli_state *cli, const void *date_ptr); -struct timespec nt_time_to_unix_timespec(NTTIME *nt); bool nt_time_equals(const NTTIME *nt1, const NTTIME *nt2); void TimeInit(void); void get_process_uptime(struct timeval *ret_time); @@ -1228,16 +1154,12 @@ bool get_cmdline_auth_info_smb_encrypt(void); bool get_cmdline_auth_info_use_machine_account(void); bool get_cmdline_auth_info_copy(struct user_auth_info *info); bool set_cmdline_auth_info_machine_account_creds(void); -const char *tmpdir(void); bool add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid, gid_t **gids, size_t *num_gids); const char *get_numlist(const char *p, uint32 **num, int *count); bool file_exist_stat(const char *fname,SMB_STRUCT_STAT *sbuf); -bool file_exist(const char *fname); bool socket_exist(const char *fname); -time_t file_modtime(const char *fname); bool directory_exist_stat(char *dname,SMB_STRUCT_STAT *st); -bool directory_exist(const char *dname); SMB_OFF_T get_file_size(char *file_name); char *attrib_string(uint16 mode); void show_msg(char *buf); @@ -1256,22 +1178,18 @@ bool reinit_after_fork(struct messaging_context *msg_ctx, bool parent_longlived); bool yesno(const char *p); void *malloc_(size_t size); -void *malloc_array(size_t el_size, unsigned int count); void *memalign_array(size_t el_size, size_t align, unsigned int count); void *calloc_array(size_t size, size_t nmemb); void *Realloc(void *p, size_t size, bool free_old_on_error); -void *realloc_array(void *p, size_t el_size, unsigned int count, bool free_old_on_error); void add_to_large_array(TALLOC_CTX *mem_ctx, size_t element_size, void *element, void *_array, uint32 *num_elements, ssize_t *array_size); -void safe_free(void *p); char *talloc_get_myname(TALLOC_CTX *ctx); char *get_mydnsdomname(TALLOC_CTX *ctx); int interpret_protocol(const char *str,int def); char *automount_lookup(TALLOC_CTX *ctx, const char *user_name); char *automount_lookup(TALLOC_CTX *ctx, const char *user_name); bool process_exists(const struct server_id pid); -bool process_exists_by_pid(pid_t pid); const char *uidtoname(uid_t uid); char *gidtoname(gid_t gid); uid_t nametouid(const char *name); @@ -1290,20 +1208,12 @@ void ra_lanman_string( const char *native_lanman ); const char *get_remote_arch_str(void); void set_remote_arch(enum remote_arch_types type); enum remote_arch_types get_remote_arch(void); -void print_asc(int level, const unsigned char *buf,int len); -void dump_data(int level, const unsigned char *buf1,int len); -void dump_data_pw(const char *msg, const uchar * data, size_t len); -void dump_data_skip_zeros(int level, const uint8_t *buf, int len); const char *tab_depth(int level, int depth); int str_checksum(const char *s); void zero_free(void *p, size_t size); int set_maxfiles(int requested_max); int smb_mkstemp(char *name_template); void *smb_xmalloc_array(size_t size, unsigned int count); -void *smb_xmemdup(const void *p, size_t size); -char *smb_xstrdup(const char *s); -char *smb_xstrndup(const char *s, size_t n); -void *memdup(const void *p, size_t size); char *myhostname(void); char *lock_path(const char *name); char *pid_path(const char *name); @@ -1364,17 +1274,8 @@ const char *strip_hostname(const char *s); /* The following definitions come from lib/util_file.c */ -char *fgets_slash(char *s2,int maxlen,XFILE *f); -char *file_load(const char *fname, size_t *size, size_t maxsize, TALLOC_CTX *mem_ctx); -char **file_lines_parse(char *p, size_t size, int *numlines, TALLOC_CTX *mem_ctx); -bool unmap_file(void* start, size_t size); -void *map_file(const char *fname, size_t size); -char **file_lines_load(const char *fname, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx); -char **fd_lines_load(int fd, int *numlines, size_t maxsize, TALLOC_CTX *mem_ctx); char **file_lines_pload(const char *syscmd, int *numlines); void file_lines_free(char **lines); -void file_lines_slashcont(char **lines); -bool file_save(const char *fname, const void *packet, size_t length); /* The following definitions come from lib/util_nscd.c */ @@ -1486,21 +1387,15 @@ NTSTATUS sid_array_from_info3(TALLOC_CTX *mem_ctx, bool interpret_string_addr_internal(struct addrinfo **ppres, const char *str, int flags); -bool is_ipaddress_v4(const char *str); -bool is_ipaddress(const char *str); bool is_broadcast_addr(const struct sockaddr *pss); -uint32 interpret_addr(const char *str); -struct in_addr interpret_addr2(const char *str); bool interpret_string_addr(struct sockaddr_storage *pss, const char *str, int flags); bool is_loopback_ip_v4(struct in_addr ip); bool is_loopback_addr(const struct sockaddr *pss); -bool is_zero_ip_v4(struct in_addr ip); bool is_zero_addr(const struct sockaddr *pss); void zero_ip_v4(struct in_addr *ip); void zero_addr(struct sockaddr_storage *pss); -bool same_net_v4(struct in_addr ip1,struct in_addr ip2,struct in_addr mask); void in_addr_to_sockaddr_storage(struct sockaddr_storage *ss, struct in_addr ip); bool same_net(const struct sockaddr *ip1, @@ -1581,22 +1476,17 @@ bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx, const char *sep); int StrCaseCmp(const char *s, const char *t); int StrnCaseCmp(const char *s, const char *t, size_t len); -bool strequal(const char *s1, const char *s2); bool strnequal(const char *s1,const char *s2,size_t n); bool strcsequal(const char *s1,const char *s2); -int strwicmp(const char *psz1, const char *psz2); void strnorm(char *s, int case_default); bool strisnormal(const char *s, int case_default); -void string_replace( char *s, char oldc, char newc ); char *push_skip_string(char *buf); char *skip_string(const char *base, size_t len, char *buf); size_t str_charnum(const char *s); size_t str_ascii_charnum(const char *s); bool trim_char(char *s,char cfront,char cback); -bool trim_string(char *s,const char *front,const char *back); bool strhasupper(const char *s); bool strhaslower(const char *s); -size_t count_chars(const char *s,char c); char *safe_strcpy_fn(const char *fn, int line, char *dest, @@ -1614,9 +1504,6 @@ char *alpha_strcpy_fn(const char *fn, const char *other_safe_chars, size_t maxlength); char *StrnCpy_fn(const char *fn, int line,char *dest,const char *src,size_t n); -size_t strhex_to_str(char *buf, size_t buf_len, const char *strhex, size_t strhex_len); -DATA_BLOB strhex_to_data_blob(TALLOC_CTX *mem_ctx, const char *strhex); -char *hex_encode_talloc(TALLOC_CTX *mem_ctx, const unsigned char *buff_in, size_t len); bool in_list(const char *s, const char *list, bool casesensitive); void string_free(char **s); bool string_set(char **dest,const char *src); @@ -1664,10 +1551,6 @@ size_t strlen_m_term_null(const char *s); char *binary_string_rfc2254(char *buf, int len); char *binary_string(char *buf, int len); int fstr_sprintf(fstring s, const char *fmt, ...); -char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep); -char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list); -bool str_list_equal(const char **list1, const char **list2); -size_t str_list_length( const char * const*list ); bool str_list_sub_basic( char **list, const char *smb_name, const char *domain_name ); bool str_list_substitute(char **list, const char *pattern, const char *insert); @@ -1698,10 +1581,8 @@ char *sstring_sub(const char *src, char front, char back); bool validate_net_name( const char *name, const char *invalid_chars, int max_len); -size_t ascii_len_n(const char *src, size_t n); -size_t utf16_len(const void *buf); -size_t utf16_len_n(const void *src, size_t n); char *escape_shell_string(const char *src); +char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string, const char *sep); /* The following definitions come from lib/util_unistr.c */ @@ -1825,25 +1706,6 @@ void wins_srv_tags_free(char **list); struct in_addr wins_srv_ip_tag(const char *tag, struct in_addr src_ip); unsigned wins_srv_count_tag(const char *tag); -/* The following definitions come from lib/xfile.c */ - -int x_setvbuf(XFILE *f, char *buf, int mode, size_t size); -XFILE *x_fopen(const char *fname, int flags, mode_t mode); -XFILE *x_fdup(const XFILE *f); -int x_fclose(XFILE *f); -size_t x_fwrite(const void *p, size_t size, size_t nmemb, XFILE *f); -int x_fileno(const XFILE *f); -int x_fflush(XFILE *f); -void x_setbuffer(XFILE *f, char *buf, size_t size); -void x_setbuf(XFILE *f, char *buf); -void x_setlinebuf(XFILE *f); -int x_feof(XFILE *f); -int x_ferror(XFILE *f); -int x_fgetc(XFILE *f); -size_t x_fread(void *p, size_t size, size_t nmemb, XFILE *f); -char *x_fgets(char *s, int size, XFILE *stream) ; -off_t x_tseek(XFILE *f, off_t offset, int whence); - /* The following definitions come from libads/ads_status.c */ ADS_STATUS ads_build_error(enum ads_error_type etype, @@ -3075,12 +2937,6 @@ void netlogon_creds_client_step(struct dcinfo *dc, const char *dcerpc_errstr(TALLOC_CTX *mem_ctx, uint32_t fault_code); -/* The following definitions come from libsmb/doserr.c */ - -const char *dos_errstr(WERROR werror); -const char *get_friendly_werror_msg(WERROR werror); -const char *win_errstr(WERROR werror); - /* The following definitions come from libsmb/dsgetdcname.c */ void debug_dsdcinfo_flags(int lvl, uint32_t flags); @@ -5694,7 +5550,8 @@ void init_netr_SamInfo3(struct netr_SamInfo3 *r, uint32_t sidcount, struct netr_SidAttr *sids); NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, - uint8_t pipe_session_key[16], + uint8_t *pipe_session_key, + size_t pipe_session_key_len, struct netr_SamInfo3 *sam3); void init_netr_IdentityInfo(struct netr_IdentityInfo *r, const char *domain_name, @@ -7126,7 +6983,7 @@ void init_rpc_pipe_hnd(void); bool fsp_is_np(struct files_struct *fsp); NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn, const char *name, struct files_struct **pfsp); -NTSTATUS np_write(struct files_struct *fsp, uint8_t *data, size_t len, +NTSTATUS np_write(struct files_struct *fsp, const uint8_t *data, size_t len, ssize_t *nwritten); NTSTATUS np_read(struct files_struct *fsp, uint8_t *data, size_t len, ssize_t *nread, bool *is_data_outstanding); @@ -7743,7 +7600,7 @@ int wait_for_aio_completion(files_struct *fsp); /* The following definitions come from smbd/blocking.c */ bool push_blocking_lock_request( struct byte_range_lock *br_lck, - const struct smb_request *req, + struct smb_request *req, files_struct *fsp, int lock_timeout, int lock_num, @@ -8017,7 +7874,7 @@ NTSTATUS dup_file_fsp(struct smb_request *req, files_struct *fsp, /* The following definitions come from smbd/ipc.c */ void send_trans_reply(connection_struct *conn, - const uint8_t *inbuf, + struct smb_request *req, char *rparam, int rparam_len, char *rdata, int rdata_len, bool buffer_too_large); @@ -8116,11 +7973,11 @@ void reply_negprot(struct smb_request *req); /* The following definitions come from smbd/notify.c */ void change_notify_reply(connection_struct *conn, - const uint8 *request_buf, uint32 max_param, + struct smb_request *req, uint32 max_param, struct notify_change_buf *notify_buf); NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, bool recursive); -NTSTATUS change_notify_add_request(const struct smb_request *req, +NTSTATUS change_notify_add_request(struct smb_request *req, uint32 max_param, uint32 filter, bool recursive, struct files_struct *fsp); @@ -8185,6 +8042,10 @@ void reply_nttranss(struct smb_request *req); /* The following definitions come from smbd/open.c */ +NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd, + const NT_USER_TOKEN *token, + uint32_t access_desired, + uint32_t *access_granted); NTSTATUS fd_close(files_struct *fsp); bool map_open_params_to_ntcreate(const char *fname, int deny_mode, int open_func, uint32 *paccess_mask, @@ -8372,7 +8233,7 @@ void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes); const char *smb_fn_name(int type); void add_to_common_flags2(uint32 v); void remove_from_common_flags2(uint32 v); -void construct_reply_common(const char *inbuf, char *outbuf); +void construct_reply_common_req(struct smb_request *req, char *outbuf); void chain_reply(struct smb_request *req); void check_reload(time_t t); void smbd_process(void); @@ -8414,6 +8275,12 @@ size_t srvstr_get_path(TALLOC_CTX *ctx, size_t src_len, int flags, NTSTATUS *err); +size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req, + char **pp_dest, const char *src, int flags, + NTSTATUS *err, bool *contains_wcard); +size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req, + char **pp_dest, const char *src, int flags, + NTSTATUS *err); bool check_fsp_open(connection_struct *conn, struct smb_request *req, files_struct *fsp); bool check_fsp(connection_struct *conn, struct smb_request *req, @@ -8499,9 +8366,12 @@ NTSTATUS copy_file(TALLOC_CTX *ctx, int count, bool target_is_directory); void reply_copy(struct smb_request *req); -uint32 get_lock_pid( char *data, int data_offset, bool large_file_format); -uint64_t get_lock_count( char *data, int data_offset, bool large_file_format); -uint64_t get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err); +uint32 get_lock_pid(const uint8_t *data, int data_offset, + bool large_file_format); +uint64_t get_lock_count(const uint8_t *data, int data_offset, + bool large_file_format); +uint64_t get_lock_offset(const uint8_t *data, int data_offset, + bool large_file_format, bool *err); void reply_lockingX(struct smb_request *req); void reply_readbmpx(struct smb_request *req); void reply_readbs(struct smb_request *req); diff --git a/source3/include/rpc_secdes.h b/source3/include/rpc_secdes.h index fb73498b0d..a1cfad9003 100644 --- a/source3/include/rpc_secdes.h +++ b/source3/include/rpc_secdes.h @@ -146,21 +146,6 @@ struct standard_mapping { #define STD_RIGHT_ALL_ACCESS 0x001F0000 -/* Combinations of standard masks. */ -#define STANDARD_RIGHTS_ALL_ACCESS STD_RIGHT_ALL_ACCESS /* 0x001f0000 */ -#define STANDARD_RIGHTS_MODIFY_ACCESS STD_RIGHT_READ_CONTROL_ACCESS /* 0x00020000 */ -#define STANDARD_RIGHTS_EXECUTE_ACCESS STD_RIGHT_READ_CONTROL_ACCESS /* 0x00020000 */ -#define STANDARD_RIGHTS_READ_ACCESS STD_RIGHT_READ_CONTROL_ACCESS /* 0x00020000 */ -#define STANDARD_RIGHTS_WRITE_ACCESS \ - (STD_RIGHT_WRITE_OWNER_ACCESS | \ - STD_RIGHT_WRITE_DAC_ACCESS | \ - STD_RIGHT_DELETE_ACCESS) /* 0x000d0000 */ -#define STANDARD_RIGHTS_REQUIRED_ACCESS \ - (STD_RIGHT_DELETE_ACCESS | \ - STD_RIGHT_READ_CONTROL_ACCESS | \ - STD_RIGHT_WRITE_DAC_ACCESS | \ - STD_RIGHT_WRITE_OWNER_ACCESS) /* 0x000f0000 */ - /* File Object specific access rights */ #define SA_RIGHT_FILE_READ_DATA 0x00000001 @@ -214,177 +199,6 @@ struct standard_mapping { SA_RIGHT_FILE_WRITE_DATA | \ SA_RIGHT_FILE_READ_DATA) -/* SAM server specific access rights */ - -#define SA_RIGHT_SAM_CONNECT_SERVER 0x00000001 -#define SA_RIGHT_SAM_SHUTDOWN_SERVER 0x00000002 -#define SA_RIGHT_SAM_INITIALISE_SERVER 0x00000004 -#define SA_RIGHT_SAM_CREATE_DOMAIN 0x00000008 -#define SA_RIGHT_SAM_ENUM_DOMAINS 0x00000010 -#define SA_RIGHT_SAM_OPEN_DOMAIN 0x00000020 - -#define SA_RIGHT_SAM_ALL_ACCESS 0x0000003F - -#define GENERIC_RIGHTS_SAM_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED_ACCESS| \ - SA_RIGHT_SAM_ALL_ACCESS) - -#define GENERIC_RIGHTS_SAM_READ \ - (STANDARD_RIGHTS_READ_ACCESS | \ - SA_RIGHT_SAM_ENUM_DOMAINS) - -#define GENERIC_RIGHTS_SAM_WRITE \ - (STANDARD_RIGHTS_WRITE_ACCESS | \ - SA_RIGHT_SAM_CREATE_DOMAIN | \ - SA_RIGHT_SAM_INITIALISE_SERVER | \ - SA_RIGHT_SAM_SHUTDOWN_SERVER) - -#define GENERIC_RIGHTS_SAM_EXECUTE \ - (STANDARD_RIGHTS_EXECUTE_ACCESS | \ - SA_RIGHT_SAM_OPEN_DOMAIN | \ - SA_RIGHT_SAM_CONNECT_SERVER) - - -/* Domain Object specific access rights */ - -#define SA_RIGHT_DOMAIN_LOOKUP_INFO_1 0x00000001 -#define SA_RIGHT_DOMAIN_SET_INFO_1 0x00000002 -#define SA_RIGHT_DOMAIN_LOOKUP_INFO_2 0x00000004 -#define SA_RIGHT_DOMAIN_SET_INFO_2 0x00000008 -#define SA_RIGHT_DOMAIN_CREATE_USER 0x00000010 -#define SA_RIGHT_DOMAIN_CREATE_GROUP 0x00000020 -#define SA_RIGHT_DOMAIN_CREATE_ALIAS 0x00000040 -#define SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM 0x00000080 -#define SA_RIGHT_DOMAIN_ENUM_ACCOUNTS 0x00000100 -#define SA_RIGHT_DOMAIN_OPEN_ACCOUNT 0x00000200 -#define SA_RIGHT_DOMAIN_SET_INFO_3 0x00000400 - -#define SA_RIGHT_DOMAIN_ALL_ACCESS 0x000007FF - -#define GENERIC_RIGHTS_DOMAIN_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED_ACCESS| \ - SA_RIGHT_DOMAIN_ALL_ACCESS) - -#define GENERIC_RIGHTS_DOMAIN_READ \ - (STANDARD_RIGHTS_READ_ACCESS | \ - SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM | \ - SA_RIGHT_DOMAIN_LOOKUP_INFO_2) - -#define GENERIC_RIGHTS_DOMAIN_WRITE \ - (STANDARD_RIGHTS_WRITE_ACCESS | \ - SA_RIGHT_DOMAIN_SET_INFO_3 | \ - SA_RIGHT_DOMAIN_CREATE_ALIAS | \ - SA_RIGHT_DOMAIN_CREATE_GROUP | \ - SA_RIGHT_DOMAIN_CREATE_USER | \ - SA_RIGHT_DOMAIN_SET_INFO_2 | \ - SA_RIGHT_DOMAIN_SET_INFO_1) - -#define GENERIC_RIGHTS_DOMAIN_EXECUTE \ - (STANDARD_RIGHTS_EXECUTE_ACCESS | \ - SA_RIGHT_DOMAIN_OPEN_ACCOUNT | \ - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS | \ - SA_RIGHT_DOMAIN_LOOKUP_INFO_1) - - -/* User Object specific access rights */ - -#define SA_RIGHT_USER_GET_NAME_ETC 0x00000001 -#define SA_RIGHT_USER_GET_LOCALE 0x00000002 -#define SA_RIGHT_USER_SET_LOC_COM 0x00000004 -#define SA_RIGHT_USER_GET_LOGONINFO 0x00000008 -#define SA_RIGHT_USER_ACCT_FLAGS_EXPIRY 0x00000010 -#define SA_RIGHT_USER_SET_ATTRIBUTES 0x00000020 -#define SA_RIGHT_USER_CHANGE_PASSWORD 0x00000040 -#define SA_RIGHT_USER_SET_PASSWORD 0x00000080 -#define SA_RIGHT_USER_GET_GROUPS 0x00000100 -#define SA_RIGHT_USER_READ_GROUP_MEM 0x00000200 -#define SA_RIGHT_USER_CHANGE_GROUP_MEM 0x00000400 - -#define SA_RIGHT_USER_ALL_ACCESS 0x000007FF - -#define GENERIC_RIGHTS_USER_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED_ACCESS| \ - SA_RIGHT_USER_ALL_ACCESS) /* 0x000f07ff */ - -#define GENERIC_RIGHTS_USER_READ \ - (STANDARD_RIGHTS_READ_ACCESS | \ - SA_RIGHT_USER_READ_GROUP_MEM | \ - SA_RIGHT_USER_GET_GROUPS | \ - SA_RIGHT_USER_ACCT_FLAGS_EXPIRY | \ - SA_RIGHT_USER_GET_LOGONINFO | \ - SA_RIGHT_USER_GET_LOCALE) /* 0x0002031a */ - -#define GENERIC_RIGHTS_USER_WRITE \ - (STANDARD_RIGHTS_WRITE_ACCESS | \ - SA_RIGHT_USER_CHANGE_PASSWORD | \ - SA_RIGHT_USER_SET_LOC_COM | \ - SA_RIGHT_USER_SET_ATTRIBUTES | \ - SA_RIGHT_USER_SET_PASSWORD | \ - SA_RIGHT_USER_CHANGE_GROUP_MEM) /* 0x000204e4 */ - -#define GENERIC_RIGHTS_USER_EXECUTE \ - (STANDARD_RIGHTS_EXECUTE_ACCESS | \ - SA_RIGHT_USER_CHANGE_PASSWORD | \ - SA_RIGHT_USER_GET_NAME_ETC ) /* 0x00020041 */ - - -/* Group Object specific access rights */ - -#define SA_RIGHT_GROUP_LOOKUP_INFO 0x00000001 -#define SA_RIGHT_GROUP_SET_INFO 0x00000002 -#define SA_RIGHT_GROUP_ADD_MEMBER 0x00000004 -#define SA_RIGHT_GROUP_REMOVE_MEMBER 0x00000008 -#define SA_RIGHT_GROUP_GET_MEMBERS 0x00000010 - -#define SA_RIGHT_GROUP_ALL_ACCESS 0x0000001F - -#define GENERIC_RIGHTS_GROUP_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED_ACCESS| \ - SA_RIGHT_GROUP_ALL_ACCESS) /* 0x000f001f */ - -#define GENERIC_RIGHTS_GROUP_READ \ - (STANDARD_RIGHTS_READ_ACCESS | \ - SA_RIGHT_GROUP_GET_MEMBERS) /* 0x00020010 */ - -#define GENERIC_RIGHTS_GROUP_WRITE \ - (STANDARD_RIGHTS_WRITE_ACCESS | \ - SA_RIGHT_GROUP_REMOVE_MEMBER | \ - SA_RIGHT_GROUP_ADD_MEMBER | \ - SA_RIGHT_GROUP_SET_INFO ) /* 0x0002000e */ - -#define GENERIC_RIGHTS_GROUP_EXECUTE \ - (STANDARD_RIGHTS_EXECUTE_ACCESS | \ - SA_RIGHT_GROUP_LOOKUP_INFO) /* 0x00020001 */ - - -/* Alias Object specific access rights */ - -#define SA_RIGHT_ALIAS_ADD_MEMBER 0x00000001 -#define SA_RIGHT_ALIAS_REMOVE_MEMBER 0x00000002 -#define SA_RIGHT_ALIAS_GET_MEMBERS 0x00000004 -#define SA_RIGHT_ALIAS_LOOKUP_INFO 0x00000008 -#define SA_RIGHT_ALIAS_SET_INFO 0x00000010 - -#define SA_RIGHT_ALIAS_ALL_ACCESS 0x0000001F - -#define GENERIC_RIGHTS_ALIAS_ALL_ACCESS \ - (STANDARD_RIGHTS_REQUIRED_ACCESS| \ - SA_RIGHT_ALIAS_ALL_ACCESS) /* 0x000f001f */ - -#define GENERIC_RIGHTS_ALIAS_READ \ - (STANDARD_RIGHTS_READ_ACCESS | \ - SA_RIGHT_ALIAS_GET_MEMBERS ) /* 0x00020004 */ - -#define GENERIC_RIGHTS_ALIAS_WRITE \ - (STANDARD_RIGHTS_WRITE_ACCESS | \ - SA_RIGHT_ALIAS_REMOVE_MEMBER | \ - SA_RIGHT_ALIAS_ADD_MEMBER | \ - SA_RIGHT_ALIAS_SET_INFO ) /* 0x00020013 */ - -#define GENERIC_RIGHTS_ALIAS_EXECUTE \ - (STANDARD_RIGHTS_EXECUTE_ACCESS | \ - SA_RIGHT_ALIAS_LOOKUP_INFO ) /* 0x00020008 */ - /* * Access Bits for registry ACLS */ diff --git a/source3/include/smb.h b/source3/include/smb.h index 8b64877d86..bcf605ee53 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -625,12 +625,16 @@ struct current_user { }; struct smb_request { + uint8_t cmd; uint16 flags2; uint16 smbpid; uint16 mid; uint16 vuid; uint16 tid; uint8 wct; + uint16_t *vwv; + uint16_t buflen; + const uint8_t *buf; const uint8 *inbuf; uint8 *outbuf; size_t unread_bytes; @@ -1228,7 +1232,7 @@ struct bitmap { #define FILE_GENERIC_WRITE (STD_RIGHT_READ_CONTROL_ACCESS|FILE_WRITE_DATA|FILE_WRITE_ATTRIBUTES|\ FILE_WRITE_EA|FILE_APPEND_DATA|SYNCHRONIZE_ACCESS) -#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|\ +#define FILE_GENERIC_EXECUTE (STANDARD_RIGHTS_EXECUTE_ACCESS|FILE_READ_ATTRIBUTES|\ FILE_EXECUTE|SYNCHRONIZE_ACCESS) /* Share specific rights. */ diff --git a/source3/include/smb_macros.h b/source3/include/smb_macros.h index d2e0aa95ac..119ceeb158 100644 --- a/source3/include/smb_macros.h +++ b/source3/include/smb_macros.h @@ -34,29 +34,6 @@ #define IS_DOS_SYSTEM(test_mode) (((test_mode) & aSYSTEM) != 0) #define IS_DOS_HIDDEN(test_mode) (((test_mode) & aHIDDEN) != 0) -#ifndef SAFE_FREE /* Oh no this is also defined in tdb.h */ - -/** - * Free memory if the pointer and zero the pointer. - * - * @note You are explicitly allowed to pass NULL pointers -- they will - * always be ignored. - **/ -#define SAFE_FREE(x) do { if ((x) != NULL) {free(x); x=NULL;} } while(0) -#endif - -/* assert macros */ -#ifdef DEVELOPER -#define SMB_ASSERT(b) ( (b) ? (void)0 : \ - (DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \ - __FILE__, __LINE__, #b)), smb_panic("assert failed: " #b))) -#else -/* redefine the assert macro for non-developer builds */ -#define SMB_ASSERT(b) ( (b) ? (void)0 : \ - (DEBUG(0,("PANIC: assert failed at %s(%d): %s\n", \ - __FILE__, __LINE__, #b)))) -#endif - #define SMB_WARN(condition, message) \ ((condition) ? (void)0 : \ DEBUG(0, ("WARNING: %s: %s\n", #condition, message))) @@ -75,8 +52,8 @@ return ERROR_NT(NT_STATUS_INVALID_HANDLE); \ } while(0) -#define CHECK_READ(fsp,inbuf) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \ - ((SVAL((inbuf),smb_flg2) & FLAGS2_READ_PERMIT_EXECUTE) && \ +#define CHECK_READ(fsp,req) (((fsp)->fh->fd != -1) && ((fsp)->can_read || \ + ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) && \ (fsp->access_mask & FILE_EXECUTE)))) #define CHECK_WRITE(fsp) ((fsp)->can_write && ((fsp)->fh->fd != -1)) @@ -115,17 +92,6 @@ #define VALID_STAT_OF_DIR(st) (VALID_STAT(st) && S_ISDIR((st).st_mode)) #define SET_STAT_INVALID(st) ((st).st_nlink = 0) -#ifndef MIN -#define MIN(a,b) ((a)<(b)?(a):(b)) -#endif -#ifndef MAX -#define MAX(a,b) ((a)>(b)?(a):(b)) -#endif - -#ifndef ABS -#define ABS(a) ((a)>0?(a):(-(a))) -#endif - /* Macros to get at offsets within smb_lkrng and smb_unlkrng structures. We cannot define these as actual structures due to possible differences in structure packing @@ -165,6 +131,8 @@ /* the remaining number of bytes in smb buffer 'buf' from pointer 'p'. */ #define smb_bufrem(buf, p) (smb_buflen(buf)-PTR_DIFF(p, smb_buf(buf))) +#define smbreq_bufrem(req, p) (req->buflen - PTR_DIFF(p, req->buf)) + /* Note that chain_size must be available as an extern int to this macro. */ #define smb_offset(p,buf) (PTR_DIFF(p,buf+4) + chain_size) @@ -361,14 +329,6 @@ do { \ #define ADD_TO_LARGE_ARRAY(mem_ctx, type, elem, array, num, size) \ add_to_large_array((mem_ctx), sizeof(type), &(elem), (void *)(array), (num), (size)); -#ifndef ISDOT -#define ISDOT(p) (*(p) == '.' && *((p) + 1) == '\0') -#endif /* ISDOT */ - -#ifndef ISDOTDOT -#define ISDOTDOT(p) (*(p) == '.' && *((p) + 1) == '.' && *((p) + 2) == '\0') -#endif /* ISDOTDOT */ - #ifndef toupper_ascii_fast /* Warning - this must only be called with 0 <= c < 128. IT WILL * GIVE GARBAGE if c > 128 or c < 0. JRA. diff --git a/source3/include/srvstr.h b/source3/include/srvstr.h index 588a807f64..7e7d8a2e92 100644 --- a/source3/include/srvstr.h +++ b/source3/include/srvstr.h @@ -17,10 +17,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define srvstr_pull(base_ptr, smb_flags2, dest, src, dest_len, src_len, flags) \ - pull_string(base_ptr, smb_flags2, dest, src, dest_len, src_len, flags) - -/* talloc version of above. */ #define srvstr_pull_talloc(ctx, base_ptr, smb_flags2, dest, src, src_len, flags) \ pull_string_talloc(ctx, base_ptr, smb_flags2, dest, src, src_len, flags) @@ -29,9 +25,6 @@ end of the smbbuf area */ -#define srvstr_pull_buf(inbuf, smb_flags2, dest, src, dest_len, flags) \ - pull_string(inbuf, smb_flags2, dest, src, dest_len, smb_bufrem(inbuf, src), flags) - -/* talloc version of above. */ -#define srvstr_pull_buf_talloc(ctx, inbuf, smb_flags2, dest, src, flags) \ - pull_string_talloc(ctx, inbuf, smb_flags2, dest, src, smb_bufrem(inbuf, src), flags) +#define srvstr_pull_req_talloc(ctx, req_, dest, src, flags) \ + pull_string_talloc(ctx, req_->inbuf, req_->flags2, dest, src, \ + smbreq_bufrem(req_, src), flags) diff --git a/source3/lib/debug.c b/source3/lib/debug.c index be2707b595..d64fcb66d9 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -472,7 +472,7 @@ bool debug_parse_levels(const char *params_str) if (AllowDebugChange == False) return True; - params = str_list_make(talloc_tos(), params_str, NULL); + params = str_list_make_v3(talloc_tos(), params_str, NULL); if (debug_parse_params(params)) { debug_dump_status(5); @@ -680,8 +680,8 @@ bool reopen_logs( void ) force_check_log_size(); (void)umask(oldumask); - /* Take over stderr to catch ouput into logs */ - if (dbf && sys_dup2(x_fileno(dbf), 2) == -1) { + /* Take over stderr to catch output into logs */ + if (dbf && dup2(x_fileno(dbf), 2) == -1) { close_low_fds(True); /* Close stderr too, if dup2 can't point it at the logfile */ } diff --git a/source3/lib/fault.c b/source3/lib/fault.c index d4c1142937..d038e57e1a 100644 --- a/source3/lib/fault.c +++ b/source3/lib/fault.c @@ -129,7 +129,7 @@ void dump_core_setup(const char *progname) } mkdir(corepath,0700); - sys_chown(corepath,getuid(),getgid()); + chown(corepath,getuid(),getgid()); chmod(corepath,0700); SAFE_FREE(logbase); diff --git a/source3/lib/memcache.c b/source3/lib/memcache.c index 9c892fedfa..d586f707fa 100644 --- a/source3/lib/memcache.c +++ b/source3/lib/memcache.c @@ -40,37 +40,11 @@ struct memcache { static void memcache_element_parse(struct memcache_element *e, DATA_BLOB *key, DATA_BLOB *value); -static bool memcache_is_talloc(enum memcache_number n) -{ - bool result; - - switch (n) { - case GETPWNAM_CACHE: - case PDB_GETPWSID_CACHE: - case SINGLETON_CACHE_TALLOC: - result = true; - break; - default: - result = false; - break; - } - - return result; -} - static int memcache_destructor(struct memcache *cache) { struct memcache_element *e, *next; for (e = cache->mru; e != NULL; e = next) { next = e->next; - if (memcache_is_talloc((enum memcache_number)e->n) - && (e->valuelength == sizeof(void *))) { - DATA_BLOB key, value; - void *ptr; - memcache_element_parse(e, &key, &value); - memcpy(&ptr, value.data, sizeof(ptr)); - TALLOC_FREE(ptr); - } SAFE_FREE(e); } return 0; diff --git a/source3/lib/module.c b/source3/lib/module.c index 76983387ff..de13668009 100644 --- a/source3/lib/module.c +++ b/source3/lib/module.c @@ -37,11 +37,11 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) * backwards compatibility, there might be symbols in the * plugin referencing to old (removed) functions */ - handle = sys_dlopen(module_name, RTLD_LAZY); + handle = dlopen(module_name, RTLD_LAZY); /* This call should reset any possible non-fatal errors that occured since last call to dl* functions */ - error = sys_dlerror(); + error = dlerror(); if(!handle) { int level = is_probe ? 3 : 0; @@ -49,15 +49,15 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) return NT_STATUS_UNSUCCESSFUL; } - init = (init_module_function *)sys_dlsym(handle, "init_samba_module"); + init = (init_module_function *)dlsym(handle, "init_samba_module"); - /* we must check sys_dlerror() to determine if it worked, because - sys_dlsym() can validly return NULL */ - error = sys_dlerror(); + /* we must check dlerror() to determine if it worked, because + dlsym() can validly return NULL */ + error = dlerror(); if (error) { DEBUG(0, ("Error trying to resolve symbol 'init_samba_module' " "in %s: %s\n", module_name, error)); - sys_dlclose(handle); + dlclose(handle); return NT_STATUS_UNSUCCESSFUL; } @@ -67,7 +67,7 @@ static NTSTATUS do_smb_load_module(const char *module_name, bool is_probe) if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Module '%s' initialization failed: %s\n", module_name, get_friendly_nt_error_msg(status))); - sys_dlclose(handle); + dlclose(handle); } return status; diff --git a/source3/lib/popt_common.c b/source3/lib/popt_common.c index 8ceac26bf2..2e6d3b3cb1 100644 --- a/source3/lib/popt_common.c +++ b/source3/lib/popt_common.c @@ -39,7 +39,7 @@ extern bool override_logfile; static void set_logfile(poptContext con, const char * arg) { - char *logfile = NULL; + char *lfile = NULL; const char *pname; /* Find out basename of current program */ @@ -50,11 +50,11 @@ static void set_logfile(poptContext con, const char * arg) else pname++; - if (asprintf(&logfile, "%s/log.%s", arg, pname) < 0) { + if (asprintf(&lfile, "%s/log.%s", arg, pname) < 0) { return; } - lp_set_logfile(logfile); - SAFE_FREE(logfile); + lp_set_logfile(lfile); + SAFE_FREE(lfile); } static bool PrintSambaVersionString; diff --git a/source3/lib/secdesc.c b/source3/lib/secdesc.c index 1da2b3ec93..df85336603 100644 --- a/source3/lib/secdesc.c +++ b/source3/lib/secdesc.c @@ -529,7 +529,7 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx, /* First add the regular ACE entry. */ init_sec_ace(new_ace, ptrustee, ace->type, - ace->access_mask, SEC_ACE_FLAG_INHERITED_ACE); + ace->access_mask, 0); DEBUG(5,("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x" " inherited as %s:%d/0x%02x/0x%08x\n", @@ -546,10 +546,13 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx, ptrustee = creator; new_flags |= SEC_ACE_FLAG_INHERIT_ONLY; + } else if (container && + !(ace->flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT)) { + ptrustee = &ace->trustee; } init_sec_ace(new_ace, ptrustee, ace->type, - ace->access_mask, new_flags | SEC_ACE_FLAG_INHERITED_ACE); + ace->access_mask, new_flags); DEBUG(5, ("se_create_child_secdesc(): %s:%d/0x%02x/0x%08x " " inherited as %s:%d/0x%02x/0x%08x\n", @@ -563,19 +566,20 @@ NTSTATUS se_create_child_secdesc(TALLOC_CTX *ctx, } /* Create child security descriptor to return */ - - new_dacl = make_sec_acl(ctx, - ACL_REVISION, + if (new_ace_list_ndx) { + new_dacl = make_sec_acl(ctx, + NT4_ACL_REVISION, new_ace_list_ndx, new_ace_list); - if (!new_dacl) { - return NT_STATUS_NO_MEMORY; + if (!new_dacl) { + return NT_STATUS_NO_MEMORY; + } } + *ppsd = make_sec_desc(ctx, SECURITY_DESCRIPTOR_REVISION_1, - SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT| - SEC_DESC_DACL_DEFAULTED, + SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT, owner_sid, group_sid, NULL, diff --git a/source3/lib/sharesec.c b/source3/lib/sharesec.c index b90346ff7e..8ea63a5824 100644 --- a/source3/lib/sharesec.c +++ b/source3/lib/sharesec.c @@ -279,7 +279,6 @@ bool share_access_check(const NT_USER_TOKEN *token, const char *sharename, NTSTATUS status; SEC_DESC *psd = NULL; size_t sd_size; - bool ret = True; psd = get_share_security(talloc_tos(), sharename, &sd_size); diff --git a/source3/lib/smbconf/smbconf_reg.c b/source3/lib/smbconf/smbconf_reg.c index c5092895bb..cae16ad2e5 100644 --- a/source3/lib/smbconf/smbconf_reg.c +++ b/source3/lib/smbconf/smbconf_reg.c @@ -112,7 +112,7 @@ static WERROR smbconf_reg_open_path(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error opening registry path '%s': %s\n", - path, dos_errstr(werr))); + path, win_errstr(werr))); } done: @@ -212,7 +212,7 @@ static WERROR smbconf_reg_create_service_key(TALLOC_CTX *mem_ctx, } if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error creating key %s: %s\n", - subkeyname, dos_errstr(werr))); + subkeyname, win_errstr(werr))); } done: @@ -283,7 +283,7 @@ static WERROR smbconf_reg_set_value(struct registry_key *key, if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error adding value '%s' to " "key '%s': %s\n", - canon_valname, key->key->name, dos_errstr(werr))); + canon_valname, key->key->name, win_errstr(werr))); } done: @@ -327,7 +327,7 @@ static WERROR smbconf_reg_set_multi_sz_value(struct registry_key *key, werr = reg_setvalue(key, valname, value); if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error adding value '%s' to key '%s': %s\n", - valname, key->key->name, dos_errstr(werr))); + valname, key->key->name, win_errstr(werr))); } done: @@ -585,7 +585,7 @@ static WERROR smbconf_reg_delete_values(struct registry_key *key) DEBUG(1, ("smbconf_reg_delete_values: " "Error enumerating values of %s: %s\n", key->key->name, - dos_errstr(werr))); + win_errstr(werr))); goto done; } diff --git a/source3/lib/smbconf/testsuite.c b/source3/lib/smbconf/testsuite.c index 100fbe8440..edc9a7ffac 100644 --- a/source3/lib/smbconf/testsuite.c +++ b/source3/lib/smbconf/testsuite.c @@ -45,7 +45,7 @@ static bool test_get_includes(struct smbconf_ctx *ctx) werr = smbconf_get_global_includes(ctx, mem_ctx, &num_includes, &includes); if (!W_ERROR_IS_OK(werr)) { - printf("failure: get_includes - %s\n", dos_errstr(werr)); + printf("failure: get_includes - %s\n", win_errstr(werr)); goto done; } @@ -80,7 +80,7 @@ static bool test_set_get_includes(struct smbconf_ctx *ctx) werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes); if (!W_ERROR_IS_OK(werr)) { printf("failure: get_set_includes (setting includes) - %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -88,7 +88,7 @@ static bool test_set_get_includes(struct smbconf_ctx *ctx) &get_includes); if (!W_ERROR_IS_OK(werr)) { printf("failure: get_set_includes (getting includes) - %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -135,14 +135,14 @@ static bool test_delete_includes(struct smbconf_ctx *ctx) werr = smbconf_set_global_includes(ctx, set_num_includes, set_includes); if (!W_ERROR_IS_OK(werr)) { printf("failure: delete_includes (setting includes) - %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } werr = smbconf_delete_global_includes(ctx); if (!W_ERROR_IS_OK(werr)) { printf("failure: delete_includes (deleting includes) - %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -150,7 +150,7 @@ static bool test_delete_includes(struct smbconf_ctx *ctx) &get_includes); if (!W_ERROR_IS_OK(werr)) { printf("failure: delete_includes (getting includes) - %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -162,7 +162,7 @@ static bool test_delete_includes(struct smbconf_ctx *ctx) werr = smbconf_delete_global_includes(ctx); if (!W_ERROR_IS_OK(werr)) { printf("failuer: delete_includes (delete empty includes) - " - "%s\n", dos_errstr(werr)); + "%s\n", win_errstr(werr)); goto done; } @@ -214,7 +214,7 @@ static bool torture_smbconf_txt(void) printf("test: init\n"); werr = smbconf_init_txt(mem_ctx, &conf_ctx, filename); if (!W_ERROR_IS_OK(werr)) { - printf("failure: init failed: %s\n", dos_errstr(werr)); + printf("failure: init failed: %s\n", win_errstr(werr)); ret = false; goto done; } @@ -251,7 +251,7 @@ static bool torture_smbconf_reg(void) printf("test: init\n"); werr = smbconf_init_reg(mem_ctx, &conf_ctx, NULL); if (!W_ERROR_IS_OK(werr)) { - printf("failure: init failed: %s\n", dos_errstr(werr)); + printf("failure: init failed: %s\n", win_errstr(werr)); ret = false; goto done; } diff --git a/source3/lib/smbrun.c b/source3/lib/smbrun.c index 515fcd75c2..31990713b8 100644 --- a/source3/lib/smbrun.c +++ b/source3/lib/smbrun.c @@ -153,7 +153,7 @@ static int smbrun_internal(const char *cmd, int *outfd, bool sanitize) /* point our stdout at the file we want output to go into */ if (outfd) { close(1); - if (sys_dup2(*outfd,1) != 1) { + if (dup2(*outfd,1) != 1) { DEBUG(2,("Failed to create stdout file descriptor\n")); close(*outfd); exit(80); @@ -305,7 +305,7 @@ int smbrunsecret(const char *cmd, const char *secret) close(ifd[1]); close(0); - if (sys_dup2(ifd[0], 0) != 0) { + if (dup2(ifd[0], 0) != 0) { DEBUG(2,("Failed to create stdin file descriptor\n")); close(ifd[0]); exit(80); diff --git a/source3/lib/system.c b/source3/lib/system.c index eabb6d6dc4..86c4ef2097 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -538,21 +538,6 @@ int sys_mknod(const char *path, mode_t mode, SMB_DEV_T dev) } /******************************************************************* - Wrapper for realpath. -********************************************************************/ - -char *sys_realpath(const char *path, char *resolved_path) -{ -#if defined(HAVE_REALPATH) - return realpath(path, resolved_path); -#else - /* As realpath is not a system call we can't return ENOSYS. */ - errno = EINVAL; - return NULL; -#endif -} - -/******************************************************************* The wait() calls vary between systems ********************************************************************/ @@ -580,104 +565,6 @@ char *sys_getwd(char *s) return wd; } -/******************************************************************* -system wrapper for symlink -********************************************************************/ - -int sys_symlink(const char *oldpath, const char *newpath) -{ -#ifndef HAVE_SYMLINK - errno = ENOSYS; - return -1; -#else - return symlink(oldpath, newpath); -#endif -} - -/******************************************************************* -system wrapper for readlink -********************************************************************/ - -int sys_readlink(const char *path, char *buf, size_t bufsiz) -{ -#ifndef HAVE_READLINK - errno = ENOSYS; - return -1; -#else - return readlink(path, buf, bufsiz); -#endif -} - -/******************************************************************* -system wrapper for link -********************************************************************/ - -int sys_link(const char *oldpath, const char *newpath) -{ -#ifndef HAVE_LINK - errno = ENOSYS; - return -1; -#else - return link(oldpath, newpath); -#endif -} - -/******************************************************************* -chown isn't used much but OS/2 doesn't have it -********************************************************************/ - -int sys_chown(const char *fname,uid_t uid,gid_t gid) -{ -#ifndef HAVE_CHOWN - static int done; - if (!done) { - DEBUG(1,("WARNING: no chown!\n")); - done=1; - } - errno = ENOSYS; - return -1; -#else - return(chown(fname,uid,gid)); -#endif -} - -/******************************************************************* - Wrapper for lchown. -********************************************************************/ - -int sys_lchown(const char *fname,uid_t uid,gid_t gid) -{ -#ifndef HAVE_LCHOWN - static int done; - if (!done) { - DEBUG(1,("WARNING: no lchown!\n")); - done=1; - } - errno = ENOSYS; - return -1; -#else - return(lchown(fname,uid,gid)); -#endif -} - -/******************************************************************* -os/2 also doesn't have chroot -********************************************************************/ -int sys_chroot(const char *dname) -{ -#ifndef HAVE_CHROOT - static int done; - if (!done) { - DEBUG(1,("WARNING: no chroot!\n")); - done=1; - } - errno = ENOSYS; - return -1; -#else - return(chroot(dname)); -#endif -} - #if defined(HAVE_POSIX_CAPABILITIES) /************************************************************************** @@ -1304,56 +1191,6 @@ int sys_pclose(int fd) } /************************************************************************** - Wrappers for dlopen, dlsym, dlclose. -****************************************************************************/ - -void *sys_dlopen(const char *name, int flags) -{ -#if defined(HAVE_DLOPEN) - return dlopen(name, flags); -#else - return NULL; -#endif -} - -void *sys_dlsym(void *handle, const char *symbol) -{ -#if defined(HAVE_DLSYM) - return dlsym(handle, symbol); -#else - return NULL; -#endif -} - -int sys_dlclose (void *handle) -{ -#if defined(HAVE_DLCLOSE) - return dlclose(handle); -#else - return 0; -#endif -} - -const char *sys_dlerror(void) -{ -#if defined(HAVE_DLERROR) - return dlerror(); -#else - return NULL; -#endif -} - -int sys_dup2(int oldfd, int newfd) -{ -#if defined(HAVE_DUP2) - return dup2(oldfd, newfd); -#else - errno = ENOSYS; - return -1; -#endif -} - -/************************************************************************** Wrapper for Admin Logs. ****************************************************************************/ diff --git a/source3/lib/util.c b/source3/lib/util.c index 820cf376be..5007fb72ef 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1497,7 +1497,7 @@ uid_t nametouid(const char *name) char *p; uid_t u; - pass = getpwnam_alloc(NULL, name); + pass = getpwnam_alloc(talloc_autofree_context(), name); if (pass) { u = pass->pw_uid; TALLOC_FREE(pass); @@ -2255,8 +2255,8 @@ char *myhostname(void) static char *ret; if (ret == NULL) { /* This is cached forever so - * use NULL talloc ctx. */ - ret = talloc_get_myname(NULL); + * use talloc_autofree_context() ctx. */ + ret = talloc_get_myname(talloc_autofree_context()); } return ret; } diff --git a/source3/lib/util_pw.c b/source3/lib/util_pw.c index c0d37f1094..e0dbc97f00 100644 --- a/source3/lib/util_pw.c +++ b/source3/lib/util_pw.c @@ -57,7 +57,7 @@ struct passwd *getpwnam_alloc(TALLOC_CTX *mem_ctx, const char *name) return NULL; } - cached = tcopy_passwd(NULL, temp); + cached = tcopy_passwd(talloc_autofree_context(), temp); if (cached == NULL) { /* * Just don't add this into the cache, ignore the failure diff --git a/source3/lib/util_seaccess.c b/source3/lib/util_seaccess.c index 17d4b78202..fdc10f20ab 100644 --- a/source3/lib/util_seaccess.c +++ b/source3/lib/util_seaccess.c @@ -110,7 +110,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, { uint32_t denied = 0, granted = 0; unsigned i; - + if (is_sid_in_token(token, sd->owner_sid)) { granted |= SEC_STD_WRITE_DAC | SEC_STD_READ_CONTROL | SEC_STD_DELETE; } else if (user_has_privileges(token, &se_restore)) { @@ -120,7 +120,7 @@ static uint32_t access_check_max_allowed(const struct security_descriptor *sd, if (sd->dacl == NULL) { return granted & ~denied; } - + for (i = 0;i<sd->dacl->num_aces; i++) { struct security_ace *ace = &sd->dacl->aces[i]; @@ -164,10 +164,17 @@ NTSTATUS se_access_check(const struct security_descriptor *sd, /* handle the maximum allowed flag */ if (access_desired & SEC_FLAG_MAXIMUM_ALLOWED) { + uint32_t orig_access_desired = access_desired; + access_desired |= access_check_max_allowed(sd, token); access_desired &= ~SEC_FLAG_MAXIMUM_ALLOWED; *access_granted = access_desired; bits_remaining = access_desired & ~SEC_STD_DELETE; + + DEBUG(10,("se_access_check: MAX desired = 0x%x, granted = 0x%x, remaining = 0x%x\n", + orig_access_desired, + *access_granted, + bits_remaining)); } #if 0 diff --git a/source3/lib/util_str.c b/source3/lib/util_str.c index 046ce61ea3..fde4f825e8 100644 --- a/source3/lib/util_str.c +++ b/source3/lib/util_str.c @@ -2532,3 +2532,19 @@ char *escape_shell_string(const char *src) *dest++ = '\0'; return ret; } + +/*************************************************** + Wrapper for str_list_make() to restore the s3 behavior. + In samba 3.2 passing NULL or an empty string returned NULL. + + In master, it now returns a list of length 1 with the first string set + to NULL (an empty list) +***************************************************/ + +char **str_list_make_v3(TALLOC_CTX *mem_ctx, const char *string, const char *sep) +{ + if (!string || !*string) { + return NULL; + } + return str_list_make(mem_ctx, string, sep); +} diff --git a/source3/libads/ldap_printer.c b/source3/libads/ldap_printer.c index 9935e2311a..0a42f00b39 100644 --- a/source3/libads/ldap_printer.c +++ b/source3/libads/ldap_printer.c @@ -309,7 +309,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, &pol); if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to open printer %s, error is %s.\n", - printername, dos_errstr(result))); + printername, win_errstr(result))); return result; } @@ -320,7 +320,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", - printername, dos_errstr(result))); + printername, win_errstr(result))); } else { uint32 num_values = regval_ctr_numvals( dsdriver_ctr ); @@ -337,7 +337,7 @@ WERROR get_remote_printer_publishing_data(struct rpc_pipe_client *cli, if (!W_ERROR_IS_OK(result)) { DEBUG(3, ("Unable to do enumdataex on %s, error is %s.\n", - printername, dos_errstr(result))); + printername, win_errstr(result))); } else { uint32 num_values = regval_ctr_numvals( dsspooler_ctr ); diff --git a/source3/libgpo/gpext/gpext.c b/source3/libgpo/gpext/gpext.c index 2ae9e2cebf..ee4ce87c4e 100644 --- a/source3/libgpo/gpext/gpext.c +++ b/source3/libgpo/gpext/gpext.c @@ -603,7 +603,7 @@ NTSTATUS init_gp_extensions(TALLOC_CTX *mem_ctx) werr = gp_extension_store_reg(mem_ctx, reg_ctx, info); if (!W_ERROR_IS_OK(werr)) { DEBUG(1,("gp_extension_store_reg failed: %s\n", - dos_errstr(werr))); + win_errstr(werr))); TALLOC_FREE(info); gpext->methods->shutdown(); status = werror_to_ntstatus(werr); diff --git a/source3/libgpo/gpext/registry.c b/source3/libgpo/gpext/registry.c index f501498407..0a0dd9bc0e 100644 --- a/source3/libgpo/gpext/registry.c +++ b/source3/libgpo/gpext/registry.c @@ -502,7 +502,7 @@ static WERROR reg_apply_registry(TALLOC_CTX *mem_ctx, token, flags); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("failed to apply registry: %s\n", - dos_errstr(werr))); + win_errstr(werr))); goto done; } } @@ -554,7 +554,7 @@ static NTSTATUS registry_process_group_policy(ADS_STRUCT *ads, entries, num_entries); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("failed to apply registry: %s\n", - dos_errstr(werr))); + win_errstr(werr))); return werror_to_ntstatus(werr); } diff --git a/source3/libgpo/gpext/scripts.c b/source3/libgpo/gpext/scripts.c index 02c3abaa1e..ddea35c644 100644 --- a/source3/libgpo/gpext/scripts.c +++ b/source3/libgpo/gpext/scripts.c @@ -311,7 +311,7 @@ static WERROR scripts_apply(TALLOC_CTX *mem_ctx, token, flags); if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("failed to apply registry: %s\n", - dos_errstr(werr))); + win_errstr(werr))); goto done; } } diff --git a/source3/libgpo/gpo_ldap.c b/source3/libgpo/gpo_ldap.c index 0e77f0a856..26813864e5 100644 --- a/source3/libgpo/gpo_ldap.c +++ b/source3/libgpo/gpo_ldap.c @@ -44,7 +44,7 @@ bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx, goto parse_error; } - ext_list = str_list_make(mem_ctx, extension_raw, "]"); + ext_list = str_list_make_v3(mem_ctx, extension_raw, "]"); if (!ext_list) { goto parse_error; } @@ -87,7 +87,7 @@ bool ads_parse_gp_ext(TALLOC_CTX *mem_ctx, p++; } - ext_strings = str_list_make(mem_ctx, p, "}"); + ext_strings = str_list_make_v3(mem_ctx, p, "}"); if (ext_strings == NULL) { goto parse_error; } @@ -162,7 +162,7 @@ static ADS_STATUS gpo_parse_gplink(TALLOC_CTX *mem_ctx, DEBUG(10,("gpo_parse_gplink: gPLink: %s\n", gp_link_raw)); - link_list = str_list_make(mem_ctx, gp_link_raw, "]"); + link_list = str_list_make_v3(mem_ctx, gp_link_raw, "]"); if (!link_list) { goto parse_error; } diff --git a/source3/libgpo/gpo_reg.c b/source3/libgpo/gpo_reg.c index d49315021e..3d385dec14 100644 --- a/source3/libgpo/gpo_reg.c +++ b/source3/libgpo/gpo_reg.c @@ -466,13 +466,13 @@ WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx, werr = gp_secure_key(mem_ctx, flags, reg_ctx->curr_key, &token->user_sids[0]); if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("failed to secure key: %s\n", dos_errstr(werr))); + DEBUG(0,("failed to secure key: %s\n", win_errstr(werr))); goto done; } werr = gp_reg_store_groupmembership(mem_ctx, reg_ctx, token, flags); if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("failed to store group membership: %s\n", dos_errstr(werr))); + DEBUG(0,("failed to store group membership: %s\n", win_errstr(werr))); goto done; } @@ -484,7 +484,7 @@ WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx, werr = gp_del_reg_state(mem_ctx, reg_ctx->curr_key, subkeyname); if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("failed to delete old state: %s\n", dos_errstr(werr))); + DEBUG(0,("failed to delete old state: %s\n", win_errstr(werr))); /* goto done; */ } @@ -534,7 +534,7 @@ WERROR gp_reg_state_store(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("gp_reg_state_store: " "gpo_store_reg_gpovals failed for %s: %s\n", - gpo->display_name, dos_errstr(werr))); + gpo->display_name, win_errstr(werr))); goto done; } } @@ -663,7 +663,7 @@ WERROR gp_reg_state_read(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("gp_reg_state_read: " "gp_read_reg_subkey gave: %s\n", - dos_errstr(werr))); + win_errstr(werr))); goto done; } @@ -941,7 +941,7 @@ WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx, root_key, &key); /* reg_ctx->curr_key, &key); */ if (!W_ERROR_IS_OK(werr)) { - DEBUG(0,("gp_store_reg_subkey failed: %s\n", dos_errstr(werr))); + DEBUG(0,("gp_store_reg_subkey failed: %s\n", win_errstr(werr))); return werr; } @@ -957,7 +957,7 @@ WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("reg_apply_registry_entry: " "gp_secure_key failed: %s\n", - dos_errstr(werr))); + win_errstr(werr))); return werr; } break; @@ -966,7 +966,7 @@ WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("reg_apply_registry_entry: " "reg_setvalue failed: %s\n", - dos_errstr(werr))); + win_errstr(werr))); dump_reg_entry(flags, "STORE", entry); return werr; } @@ -976,7 +976,7 @@ WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("reg_apply_registry_entry: " "reg_deletevalue failed: %s\n", - dos_errstr(werr))); + win_errstr(werr))); dump_reg_entry(flags, "STORE", entry); return werr; } @@ -986,7 +986,7 @@ WERROR reg_apply_registry_entry(TALLOC_CTX *mem_ctx, if (!W_ERROR_IS_OK(werr)) { DEBUG(0,("reg_apply_registry_entry: " "reg_deleteallvalues failed: %s\n", - dos_errstr(werr))); + win_errstr(werr))); dump_reg_entry(flags, "STORE", entry); return werr; } diff --git a/source3/libnet/libnet_samsync_display.c b/source3/libnet/libnet_samsync_display.c index 47c032aac7..1dd9a1add5 100644 --- a/source3/libnet/libnet_samsync_display.c +++ b/source3/libnet/libnet_samsync_display.c @@ -126,7 +126,7 @@ static void display_group_info(uint32_t rid, struct netr_DELTA_GROUP *r) static void display_delete_group(uint32_t rid) { - d_printf("Delete Group '%d' ", rid); + d_printf("Delete Group '%d'\n", rid); } static void display_rename_group(uint32_t rid, struct netr_DELTA_RENAME *r) @@ -138,7 +138,7 @@ static void display_rename_group(uint32_t rid, struct netr_DELTA_RENAME *r) static void display_delete_user(uint32_t rid) { - d_printf("Delete User '%d' ", rid); + d_printf("Delete User '%d'\n", rid); } static void display_rename_user(uint32_t rid, struct netr_DELTA_RENAME *r) @@ -150,7 +150,7 @@ static void display_rename_user(uint32_t rid, struct netr_DELTA_RENAME *r) static void display_delete_alias(uint32_t rid) { - d_printf("Delete Alias '%d' ", rid); + d_printf("Delete Alias '%d'\n", rid); } static void display_rename_alias(uint32_t rid, struct netr_DELTA_RENAME *r) diff --git a/source3/libnet/libnet_samsync_passdb.c b/source3/libnet/libnet_samsync_passdb.c index 1faef7b3eb..7ace77cace 100644 --- a/source3/libnet/libnet_samsync_passdb.c +++ b/source3/libnet/libnet_samsync_passdb.c @@ -118,12 +118,12 @@ static NTSTATUS sam_account_from_delta(struct samu *account, pdb_set_profile_path(account, new_string, PDB_CHANGED); } - if (r->parameters.string) { + if (r->parameters.array) { DATA_BLOB mung; char *newstr; old_string = pdb_get_munged_dial(account); - mung.length = r->parameters.length; - mung.data = (uint8 *) r->parameters.string; + mung.length = r->parameters.length * 2; + mung.data = (uint8_t *) r->parameters.array; newstr = (mung.length == 0) ? NULL : base64_encode_data_blob(talloc_tos(), mung); diff --git a/source3/librpc/gen_ndr/cli_netlogon.c b/source3/librpc/gen_ndr/cli_netlogon.c index 2241d3092a..1af3249473 100644 --- a/source3/librpc/gen_ndr/cli_netlogon.c +++ b/source3/librpc/gen_ndr/cli_netlogon.c @@ -890,11 +890,11 @@ NTSTATUS rpccli_netr_DatabaseRedo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server /* [in] [charset(UTF16)] */, const char *computername /* [in] [charset(UTF16)] */, - struct netr_Authenticator credential /* [in] */, + struct netr_Authenticator *credential /* [in] [ref] */, struct netr_Authenticator *return_authenticator /* [in,out] [ref] */, - uint8_t *change_log_entry /* [in] [unique,size_is(change_log_entry_size)] */, - uint32_t change_log_entry_size /* [in] */, - struct netr_DELTA_ENUM_ARRAY *delta_enum_array /* [out] [ref] */) + struct netr_ChangeLogEntry change_log_entry /* [in] [subcontext_size(change_log_entry_size),subcontext(4)] */, + uint32_t change_log_entry_size /* [in] [value(ndr_size_netr_ChangeLogEntry(&change_log_entry,ndr->flags))] */, + struct netr_DELTA_ENUM_ARRAY **delta_enum_array /* [out] [ref] */) { struct netr_DatabaseRedo r; NTSTATUS status; diff --git a/source3/librpc/gen_ndr/cli_netlogon.h b/source3/librpc/gen_ndr/cli_netlogon.h index 09484c85d0..9f5eac15b2 100644 --- a/source3/librpc/gen_ndr/cli_netlogon.h +++ b/source3/librpc/gen_ndr/cli_netlogon.h @@ -156,11 +156,11 @@ NTSTATUS rpccli_netr_DatabaseRedo(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server /* [in] [charset(UTF16)] */, const char *computername /* [in] [charset(UTF16)] */, - struct netr_Authenticator credential /* [in] */, + struct netr_Authenticator *credential /* [in] [ref] */, struct netr_Authenticator *return_authenticator /* [in,out] [ref] */, - uint8_t *change_log_entry /* [in] [unique,size_is(change_log_entry_size)] */, - uint32_t change_log_entry_size /* [in] */, - struct netr_DELTA_ENUM_ARRAY *delta_enum_array /* [out] [ref] */); + struct netr_ChangeLogEntry change_log_entry /* [in] [subcontext_size(change_log_entry_size),subcontext(4)] */, + uint32_t change_log_entry_size /* [in] [value(ndr_size_netr_ChangeLogEntry(&change_log_entry,ndr->flags))] */, + struct netr_DELTA_ENUM_ARRAY **delta_enum_array /* [out] [ref] */); NTSTATUS rpccli_netr_LogonControl2Ex(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, const char *logon_server /* [in] [unique,charset(UTF16)] */, diff --git a/source3/librpc/gen_ndr/cli_samr.c b/source3/librpc/gen_ndr/cli_samr.c index dc0a2dfa65..7edb790286 100644 --- a/source3/librpc/gen_ndr/cli_samr.c +++ b/source3/librpc/gen_ndr/cli_samr.c @@ -2022,7 +2022,7 @@ NTSTATUS rpccli_samr_QueryUserInfo2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *user_handle /* [in] [ref] */, uint16_t level /* [in] */, - union samr_UserInfo *info /* [out] [ref,switch_is(level)] */) + union samr_UserInfo **info /* [out] [ref,switch_is(level)] */) { struct samr_QueryUserInfo2 r; NTSTATUS status; @@ -2838,7 +2838,7 @@ NTSTATUS rpccli_samr_RidToSid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *domain_handle /* [in] [ref] */, uint32_t rid /* [in] */, - struct dom_sid2 *sid /* [out] [ref] */) + struct dom_sid2 **sid /* [out] [ref] */) { struct samr_RidToSid r; NTSTATUS status; @@ -2921,8 +2921,8 @@ NTSTATUS rpccli_samr_SetDsrmPassword(struct rpc_pipe_client *cli, NTSTATUS rpccli_samr_ValidatePassword(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, enum samr_ValidatePasswordLevel level /* [in] */, - union samr_ValidatePasswordReq req /* [in] [switch_is(level)] */, - union samr_ValidatePasswordRep *rep /* [out] [ref,switch_is(level)] */) + union samr_ValidatePasswordReq *req /* [in] [ref,switch_is(level)] */, + union samr_ValidatePasswordRep **rep /* [out] [ref,switch_is(level)] */) { struct samr_ValidatePassword r; NTSTATUS status; diff --git a/source3/librpc/gen_ndr/cli_samr.h b/source3/librpc/gen_ndr/cli_samr.h index 4c7a30ef63..b57d63334e 100644 --- a/source3/librpc/gen_ndr/cli_samr.h +++ b/source3/librpc/gen_ndr/cli_samr.h @@ -255,7 +255,7 @@ NTSTATUS rpccli_samr_QueryUserInfo2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *user_handle /* [in] [ref] */, uint16_t level /* [in] */, - union samr_UserInfo *info /* [out] [ref,switch_is(level)] */); + union samr_UserInfo **info /* [out] [ref,switch_is(level)] */); NTSTATUS rpccli_samr_QueryDisplayInfo2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *domain_handle /* [in] [ref] */, @@ -375,7 +375,7 @@ NTSTATUS rpccli_samr_RidToSid(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct policy_handle *domain_handle /* [in] [ref] */, uint32_t rid /* [in] */, - struct dom_sid2 *sid /* [out] [ref] */); + struct dom_sid2 **sid /* [out] [ref] */); NTSTATUS rpccli_samr_SetDsrmPassword(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, struct lsa_String *name /* [in] [unique] */, @@ -384,6 +384,6 @@ NTSTATUS rpccli_samr_SetDsrmPassword(struct rpc_pipe_client *cli, NTSTATUS rpccli_samr_ValidatePassword(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, enum samr_ValidatePasswordLevel level /* [in] */, - union samr_ValidatePasswordReq req /* [in] [switch_is(level)] */, - union samr_ValidatePasswordRep *rep /* [out] [ref,switch_is(level)] */); + union samr_ValidatePasswordReq *req /* [in] [ref,switch_is(level)] */, + union samr_ValidatePasswordRep **rep /* [out] [ref,switch_is(level)] */); #endif /* __CLI_SAMR__ */ diff --git a/source3/librpc/gen_ndr/dom_sid.h b/source3/librpc/gen_ndr/dom_sid.h new file mode 100644 index 0000000000..57dd16855a --- /dev/null +++ b/source3/librpc/gen_ndr/dom_sid.h @@ -0,0 +1,15 @@ +/* header auto-generated by pidl */ + +#include <stdint.h> + +#define dom_sid2 dom_sid +#define dom_sid28 dom_sid +#define dom_sid0 dom_sid +#ifndef _HEADER_dom_sid +#define _HEADER_dom_sid + +struct _dummy_domsid { + uint8_t dummy; +}; + +#endif /* _HEADER_dom_sid */ diff --git a/source3/librpc/gen_ndr/misc.h b/source3/librpc/gen_ndr/misc.h index b3740faf34..e439f7f43d 100644 --- a/source3/librpc/gen_ndr/misc.h +++ b/source3/librpc/gen_ndr/misc.h @@ -2,9 +2,12 @@ #include <stdint.h> +#define netr_SamDatabaseID8Bit netr_SamDatabaseID #ifndef _HEADER_misc #define _HEADER_misc +enum netr_SamDatabaseID8Bit; + struct GUID { uint32_t time_low; uint16_t time_mid; diff --git a/source3/librpc/gen_ndr/named_pipe_auth.h b/source3/librpc/gen_ndr/named_pipe_auth.h new file mode 100644 index 0000000000..5f4ba9afb1 --- /dev/null +++ b/source3/librpc/gen_ndr/named_pipe_auth.h @@ -0,0 +1,32 @@ +/* header auto-generated by pidl */ + +#include <stdint.h> + +#include "librpc/gen_ndr/netlogon.h" +#ifndef _HEADER_named_pipe_auth +#define _HEADER_named_pipe_auth + +#define NAMED_PIPE_AUTH_MAGIC ( "NPAM" ) +union named_pipe_auth_req_info { + struct netr_SamInfo3 info1;/* [case] */ +}/* [switch_type(uint32)] */; + +struct named_pipe_auth_req { + uint32_t length;/* [value(ndr_size_named_pipe_auth_req(r,ndr->flags)-4),flag(LIBNDR_FLAG_BIGENDIAN)] */ + const char *magic;/* [value(NAMED_PIPE_AUTH_MAGIC),charset(DOS)] */ + uint32_t level; + union named_pipe_auth_req_info info;/* [switch_is(level)] */ +}/* [gensize,public] */; + +union named_pipe_auth_rep_info { +}/* [switch_type(uint32)] */; + +struct named_pipe_auth_rep { + uint32_t length;/* [value(ndr_size_named_pipe_auth_rep(r,ndr->flags)-4),flag(LIBNDR_FLAG_BIGENDIAN)] */ + const char *magic;/* [value(NAMED_PIPE_AUTH_MAGIC),charset(DOS)] */ + uint32_t level; + union named_pipe_auth_rep_info info;/* [switch_is(level)] */ + NTSTATUS status; +}/* [gensize,public] */; + +#endif /* _HEADER_named_pipe_auth */ diff --git a/source3/librpc/gen_ndr/ndr_dom_sid.h b/source3/librpc/gen_ndr/ndr_dom_sid.h new file mode 100644 index 0000000000..145ec1db46 --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_dom_sid.h @@ -0,0 +1,10 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/dom_sid.h" + +#ifndef _HEADER_NDR_dom_sid +#define _HEADER_NDR_dom_sid + +#define NDR_DOM_SID_CALL_COUNT (0) +#endif /* _HEADER_NDR_dom_sid */ diff --git a/source3/librpc/gen_ndr/ndr_named_pipe_auth.c b/source3/librpc/gen_ndr/ndr_named_pipe_auth.c new file mode 100644 index 0000000000..69412bf427 --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_named_pipe_auth.c @@ -0,0 +1,302 @@ +/* parser auto-generated by pidl */ + +#include "includes.h" +#include "librpc/gen_ndr/ndr_named_pipe_auth.h" + +#include "librpc/gen_ndr/ndr_netlogon.h" +static enum ndr_err_code ndr_push_named_pipe_auth_req_info(struct ndr_push *ndr, int ndr_flags, const union named_pipe_auth_req_info *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level)); + switch (level) { + case 0: { + break; } + + case 1: { + NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_SCALARS, &r->info1)); + break; } + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case 0: + break; + + case 1: + NDR_CHECK(ndr_push_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info1)); + break; + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_named_pipe_auth_req_info(struct ndr_pull *ndr, int ndr_flags, union named_pipe_auth_req_info *r) +{ + int level; + uint32_t _level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level)); + if (_level != level) { + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level); + } + switch (level) { + case 0: { + break; } + + case 1: { + NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_SCALARS, &r->info1)); + break; } + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case 0: + break; + + case 1: + NDR_CHECK(ndr_pull_netr_SamInfo3(ndr, NDR_BUFFERS, &r->info1)); + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_named_pipe_auth_req_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_req_info *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "named_pipe_auth_req_info"); + switch (level) { + case 0: + break; + + case 1: + ndr_print_netr_SamInfo3(ndr, "info1", &r->info1); + break; + + default: + ndr_print_bad_level(ndr, name, level); + } +} + +_PUBLIC_ enum ndr_err_code ndr_push_named_pipe_auth_req(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_req *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_uint32 = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_named_pipe_auth_req(r, ndr->flags) - 4)); + ndr->flags = _flags_save_uint32; + } + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, NAMED_PIPE_AUTH_MAGIC, 4, sizeof(uint8_t), CH_DOS)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->level)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->info, r->level)); + NDR_CHECK(ndr_push_named_pipe_auth_req_info(ndr, NDR_SCALARS, &r->info)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_named_pipe_auth_req_info(ndr, NDR_BUFFERS, &r->info)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_named_pipe_auth_req(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_req *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_uint32 = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length)); + ndr->flags = _flags_save_uint32; + } + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->magic, 4, sizeof(uint8_t), CH_DOS)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->level)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->info, r->level)); + NDR_CHECK(ndr_pull_named_pipe_auth_req_info(ndr, NDR_SCALARS, &r->info)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_named_pipe_auth_req_info(ndr, NDR_BUFFERS, &r->info)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_named_pipe_auth_req(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_req *r) +{ + ndr_print_struct(ndr, name, "named_pipe_auth_req"); + ndr->depth++; + ndr_print_uint32(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_named_pipe_auth_req(r, ndr->flags) - 4:r->length); + ndr_print_string(ndr, "magic", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?NAMED_PIPE_AUTH_MAGIC:r->magic); + ndr_print_uint32(ndr, "level", r->level); + ndr_print_set_switch_value(ndr, &r->info, r->level); + ndr_print_named_pipe_auth_req_info(ndr, "info", &r->info); + ndr->depth--; +} + +_PUBLIC_ size_t ndr_size_named_pipe_auth_req(const struct named_pipe_auth_req *r, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req); +} + +static enum ndr_err_code ndr_push_named_pipe_auth_rep_info(struct ndr_push *ndr, int ndr_flags, const union named_pipe_auth_rep_info *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, level)); + switch (level) { + case 0: { + break; } + + case 1: { + break; } + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case 0: + break; + + case 1: + break; + + default: + return ndr_push_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_named_pipe_auth_rep_info(struct ndr_pull *ndr, int ndr_flags, union named_pipe_auth_rep_info *r) +{ + int level; + uint32_t _level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &_level)); + if (_level != level) { + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u for r", _level); + } + switch (level) { + case 0: { + break; } + + case 1: { + break; } + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case 0: + break; + + case 1: + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_named_pipe_auth_rep_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_rep_info *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "named_pipe_auth_rep_info"); + switch (level) { + case 0: + break; + + case 1: + break; + + default: + ndr_print_bad_level(ndr, name, level); + } +} + +_PUBLIC_ enum ndr_err_code ndr_push_named_pipe_auth_rep(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_rep *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + { + uint32_t _flags_save_uint32 = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_named_pipe_auth_rep(r, ndr->flags) - 4)); + ndr->flags = _flags_save_uint32; + } + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, NAMED_PIPE_AUTH_MAGIC, 4, sizeof(uint8_t), CH_DOS)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->level)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->info, r->level)); + NDR_CHECK(ndr_push_named_pipe_auth_rep_info(ndr, NDR_SCALARS, &r->info)); + NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->status)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_named_pipe_auth_rep_info(ndr, NDR_BUFFERS, &r->info)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_named_pipe_auth_rep(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_rep *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + { + uint32_t _flags_save_uint32 = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_BIGENDIAN); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->length)); + ndr->flags = _flags_save_uint32; + } + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->magic, 4, sizeof(uint8_t), CH_DOS)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->level)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->info, r->level)); + NDR_CHECK(ndr_pull_named_pipe_auth_rep_info(ndr, NDR_SCALARS, &r->info)); + NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->status)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_named_pipe_auth_rep_info(ndr, NDR_BUFFERS, &r->info)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_named_pipe_auth_rep(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_rep *r) +{ + ndr_print_struct(ndr, name, "named_pipe_auth_rep"); + ndr->depth++; + ndr_print_uint32(ndr, "length", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_named_pipe_auth_rep(r, ndr->flags) - 4:r->length); + ndr_print_string(ndr, "magic", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?NAMED_PIPE_AUTH_MAGIC:r->magic); + ndr_print_uint32(ndr, "level", r->level); + ndr_print_set_switch_value(ndr, &r->info, r->level); + ndr_print_named_pipe_auth_rep_info(ndr, "info", &r->info); + ndr_print_NTSTATUS(ndr, "status", r->status); + ndr->depth--; +} + +_PUBLIC_ size_t ndr_size_named_pipe_auth_rep(const struct named_pipe_auth_rep *r, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep); +} + diff --git a/source3/librpc/gen_ndr/ndr_named_pipe_auth.h b/source3/librpc/gen_ndr/ndr_named_pipe_auth.h new file mode 100644 index 0000000000..fbef9d5f1c --- /dev/null +++ b/source3/librpc/gen_ndr/ndr_named_pipe_auth.h @@ -0,0 +1,20 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "librpc/gen_ndr/named_pipe_auth.h" + +#ifndef _HEADER_NDR_named_pipe_auth +#define _HEADER_NDR_named_pipe_auth + +#define NDR_NAMED_PIPE_AUTH_CALL_COUNT (0) +void ndr_print_named_pipe_auth_req_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_req_info *r); +enum ndr_err_code ndr_push_named_pipe_auth_req(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_req *r); +enum ndr_err_code ndr_pull_named_pipe_auth_req(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_req *r); +void ndr_print_named_pipe_auth_req(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_req *r); +size_t ndr_size_named_pipe_auth_req(const struct named_pipe_auth_req *r, int flags); +void ndr_print_named_pipe_auth_rep_info(struct ndr_print *ndr, const char *name, const union named_pipe_auth_rep_info *r); +enum ndr_err_code ndr_push_named_pipe_auth_rep(struct ndr_push *ndr, int ndr_flags, const struct named_pipe_auth_rep *r); +enum ndr_err_code ndr_pull_named_pipe_auth_rep(struct ndr_pull *ndr, int ndr_flags, struct named_pipe_auth_rep *r); +void ndr_print_named_pipe_auth_rep(struct ndr_print *ndr, const char *name, const struct named_pipe_auth_rep *r); +size_t ndr_size_named_pipe_auth_rep(const struct named_pipe_auth_rep *r, int flags); +#endif /* _HEADER_NDR_named_pipe_auth */ diff --git a/source3/librpc/gen_ndr/ndr_netlogon.c b/source3/librpc/gen_ndr/ndr_netlogon.c index 290d0fd9cd..ac23c36a7c 100644 --- a/source3/librpc/gen_ndr/ndr_netlogon.c +++ b/source3/librpc/gen_ndr/ndr_netlogon.c @@ -2513,7 +2513,7 @@ static enum ndr_err_code ndr_push_netr_DELTA_USER(struct ndr_push *ndr, int ndr_ NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->lm_password_present)); NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->password_expired)); NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->comment)); - NDR_CHECK(ndr_push_lsa_String(ndr, NDR_SCALARS, &r->parameters)); + NDR_CHECK(ndr_push_lsa_BinaryString(ndr, NDR_SCALARS, &r->parameters)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->country_code)); NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->code_page)); NDR_CHECK(ndr_push_netr_USER_PRIVATE_INFO(ndr, NDR_SCALARS, &r->user_private_info)); @@ -2540,7 +2540,7 @@ static enum ndr_err_code ndr_push_netr_DELTA_USER(struct ndr_push *ndr, int ndr_ NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword)); NDR_CHECK(ndr_push_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword)); NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->comment)); - NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->parameters)); + NDR_CHECK(ndr_push_lsa_BinaryString(ndr, NDR_BUFFERS, &r->parameters)); NDR_CHECK(ndr_push_netr_USER_PRIVATE_INFO(ndr, NDR_BUFFERS, &r->user_private_info)); NDR_CHECK(ndr_push_sec_desc_buf(ndr, NDR_BUFFERS, &r->sdbuf)); NDR_CHECK(ndr_push_lsa_String(ndr, NDR_BUFFERS, &r->profile_path)); @@ -2578,7 +2578,7 @@ static enum ndr_err_code ndr_pull_netr_DELTA_USER(struct ndr_pull *ndr, int ndr_ NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->lm_password_present)); NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->password_expired)); NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->comment)); - NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_SCALARS, &r->parameters)); + NDR_CHECK(ndr_pull_lsa_BinaryString(ndr, NDR_SCALARS, &r->parameters)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->country_code)); NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->code_page)); NDR_CHECK(ndr_pull_netr_USER_PRIVATE_INFO(ndr, NDR_SCALARS, &r->user_private_info)); @@ -2605,7 +2605,7 @@ static enum ndr_err_code ndr_pull_netr_DELTA_USER(struct ndr_pull *ndr, int ndr_ NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->lmpassword)); NDR_CHECK(ndr_pull_samr_Password(ndr, NDR_BUFFERS, &r->ntpassword)); NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->comment)); - NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->parameters)); + NDR_CHECK(ndr_pull_lsa_BinaryString(ndr, NDR_BUFFERS, &r->parameters)); NDR_CHECK(ndr_pull_netr_USER_PRIVATE_INFO(ndr, NDR_BUFFERS, &r->user_private_info)); NDR_CHECK(ndr_pull_sec_desc_buf(ndr, NDR_BUFFERS, &r->sdbuf)); NDR_CHECK(ndr_pull_lsa_String(ndr, NDR_BUFFERS, &r->profile_path)); @@ -2643,7 +2643,7 @@ _PUBLIC_ void ndr_print_netr_DELTA_USER(struct ndr_print *ndr, const char *name, ndr_print_uint8(ndr, "lm_password_present", r->lm_password_present); ndr_print_uint8(ndr, "password_expired", r->password_expired); ndr_print_lsa_String(ndr, "comment", &r->comment); - ndr_print_lsa_String(ndr, "parameters", &r->parameters); + ndr_print_lsa_BinaryString(ndr, "parameters", &r->parameters); ndr_print_uint16(ndr, "country_code", r->country_code); ndr_print_uint16(ndr, "code_page", r->code_page); ndr_print_netr_USER_PRIVATE_INFO(ndr, "user_private_info", &r->user_private_info); @@ -6232,6 +6232,192 @@ _PUBLIC_ void ndr_print_netr_NegotiateFlags(struct ndr_print *ndr, const char *n ndr->depth--; } +static enum ndr_err_code ndr_push_netr_ChangeLogFlags(struct ndr_push *ndr, int ndr_flags, uint16_t r) +{ + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_netr_ChangeLogFlags(struct ndr_pull *ndr, int ndr_flags, uint16_t *r) +{ + uint16_t v; + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_netr_ChangeLogFlags(struct ndr_print *ndr, const char *name, uint16_t r) +{ + ndr_print_uint16(ndr, name, r); + ndr->depth++; + ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED", NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_CHANGED_PASSWORD", NETR_CHANGELOG_CHANGED_PASSWORD, r); + ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_SID_INCLUDED", NETR_CHANGELOG_SID_INCLUDED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_NAME_INCLUDED", NETR_CHANGELOG_NAME_INCLUDED, r); + ndr_print_bitmap_flag(ndr, sizeof(uint16_t), "NETR_CHANGELOG_FIRST_PROMOTION_OBJ", NETR_CHANGELOG_FIRST_PROMOTION_OBJ, r); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_netr_ChangeLogObject(struct ndr_push *ndr, int ndr_flags, const union netr_ChangeLogObject *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case NETR_CHANGELOG_SID_INCLUDED: { + NDR_CHECK(ndr_push_dom_sid(ndr, NDR_SCALARS, &r->object_sid)); + break; } + + case NETR_CHANGELOG_NAME_INCLUDED: { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_push_string(ndr, NDR_SCALARS, r->object_name)); + ndr->flags = _flags_save_string; + } + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case NETR_CHANGELOG_SID_INCLUDED: + NDR_CHECK(ndr_push_dom_sid(ndr, NDR_BUFFERS, &r->object_sid)); + break; + + case NETR_CHANGELOG_NAME_INCLUDED: + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_netr_ChangeLogObject(struct ndr_pull *ndr, int ndr_flags, union netr_ChangeLogObject *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + case NETR_CHANGELOG_SID_INCLUDED: { + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->object_sid)); + break; } + + case NETR_CHANGELOG_NAME_INCLUDED: { + { + uint32_t _flags_save_string = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_STR_NULLTERM); + NDR_CHECK(ndr_pull_string(ndr, NDR_SCALARS, &r->object_name)); + ndr->flags = _flags_save_string; + } + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case NETR_CHANGELOG_SID_INCLUDED: + NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_BUFFERS, &r->object_sid)); + break; + + case NETR_CHANGELOG_NAME_INCLUDED: + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_netr_ChangeLogObject(struct ndr_print *ndr, const char *name, const union netr_ChangeLogObject *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "netr_ChangeLogObject"); + switch (level) { + case NETR_CHANGELOG_SID_INCLUDED: + ndr_print_dom_sid(ndr, "object_sid", &r->object_sid); + break; + + case NETR_CHANGELOG_NAME_INCLUDED: + ndr_print_string(ndr, "object_name", r->object_name); + break; + + default: + break; + + } +} + +_PUBLIC_ enum ndr_err_code ndr_push_netr_ChangeLogEntry(struct ndr_push *ndr, int ndr_flags, const struct netr_ChangeLogEntry *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->serial_number1)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->serial_number2)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->object_rid)); + NDR_CHECK(ndr_push_netr_ChangeLogFlags(ndr, NDR_SCALARS, r->flags)); + NDR_CHECK(ndr_push_netr_SamDatabaseID8Bit(ndr, NDR_SCALARS, r->db_index)); + NDR_CHECK(ndr_push_netr_DeltaEnum8Bit(ndr, NDR_SCALARS, r->delta_type)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, r->flags & (NETR_CHANGELOG_SID_INCLUDED | NETR_CHANGELOG_NAME_INCLUDED))); + NDR_CHECK(ndr_push_netr_ChangeLogObject(ndr, NDR_SCALARS, &r->object)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_netr_ChangeLogObject(ndr, NDR_BUFFERS, &r->object)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_netr_ChangeLogEntry(struct ndr_pull *ndr, int ndr_flags, struct netr_ChangeLogEntry *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->serial_number1)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->serial_number2)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->object_rid)); + NDR_CHECK(ndr_pull_netr_ChangeLogFlags(ndr, NDR_SCALARS, &r->flags)); + NDR_CHECK(ndr_pull_netr_SamDatabaseID8Bit(ndr, NDR_SCALARS, &r->db_index)); + NDR_CHECK(ndr_pull_netr_DeltaEnum8Bit(ndr, NDR_SCALARS, &r->delta_type)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->flags & (NETR_CHANGELOG_SID_INCLUDED | NETR_CHANGELOG_NAME_INCLUDED))); + NDR_CHECK(ndr_pull_netr_ChangeLogObject(ndr, NDR_SCALARS, &r->object)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_netr_ChangeLogObject(ndr, NDR_BUFFERS, &r->object)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_netr_ChangeLogEntry(struct ndr_print *ndr, const char *name, const struct netr_ChangeLogEntry *r) +{ + ndr_print_struct(ndr, name, "netr_ChangeLogEntry"); + ndr->depth++; + ndr_print_uint32(ndr, "serial_number1", r->serial_number1); + ndr_print_uint32(ndr, "serial_number2", r->serial_number2); + ndr_print_uint32(ndr, "object_rid", r->object_rid); + ndr_print_netr_ChangeLogFlags(ndr, "flags", r->flags); + ndr_print_netr_SamDatabaseID8Bit(ndr, "db_index", r->db_index); + ndr_print_netr_DeltaEnum8Bit(ndr, "delta_type", r->delta_type); + ndr_print_set_switch_value(ndr, &r->object, r->flags & (NETR_CHANGELOG_SID_INCLUDED | NETR_CHANGELOG_NAME_INCLUDED)); + ndr_print_netr_ChangeLogObject(ndr, "object", &r->object); + ndr->depth--; +} + +_PUBLIC_ size_t ndr_size_netr_ChangeLogEntry(const struct netr_ChangeLogEntry *r, int flags) +{ + return ndr_size_struct(r, flags, (ndr_push_flags_fn_t)ndr_push_netr_ChangeLogEntry); +} + static enum ndr_err_code ndr_push_netr_Blob(struct ndr_push *ndr, int ndr_flags, const struct netr_Blob *r) { if (ndr_flags & NDR_SCALARS) { @@ -11299,17 +11485,21 @@ static enum ndr_err_code ndr_push_netr_DatabaseRedo(struct ndr_push *ndr, int fl NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, 0)); NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_charset_length(r->in.computername, CH_UTF16))); NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->in.computername, ndr_charset_length(r->in.computername, CH_UTF16), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); + if (r->in.credential == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); if (r->in.return_authenticator == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } NDR_CHECK(ndr_push_netr_Authenticator(ndr, NDR_SCALARS, r->in.return_authenticator)); - NDR_CHECK(ndr_push_unique_ptr(ndr, r->in.change_log_entry)); - if (r->in.change_log_entry) { - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.change_log_entry_size)); - NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->in.change_log_entry, r->in.change_log_entry_size)); + { + struct ndr_push *_ndr_change_log_entry; + NDR_CHECK(ndr_push_subcontext_start(ndr, &_ndr_change_log_entry, 4, ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags))); + NDR_CHECK(ndr_push_netr_ChangeLogEntry(_ndr_change_log_entry, NDR_SCALARS|NDR_BUFFERS, &r->in.change_log_entry)); + NDR_CHECK(ndr_push_subcontext_end(ndr, _ndr_change_log_entry, 4, ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags))); } - NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->in.change_log_entry_size)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags))); } if (flags & NDR_OUT) { if (r->out.return_authenticator == NULL) { @@ -11319,7 +11509,10 @@ static enum ndr_err_code ndr_push_netr_DatabaseRedo(struct ndr_push *ndr, int fl if (r->out.delta_enum_array == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.delta_enum_array)); + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.delta_enum_array)); + if (*r->out.delta_enum_array) { + NDR_CHECK(ndr_push_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.delta_enum_array)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -11327,10 +11520,11 @@ static enum ndr_err_code ndr_push_netr_DatabaseRedo(struct ndr_push *ndr, int fl static enum ndr_err_code ndr_pull_netr_DatabaseRedo(struct ndr_pull *ndr, int flags, struct netr_DatabaseRedo *r) { - uint32_t _ptr_change_log_entry; + uint32_t _ptr_delta_enum_array; + TALLOC_CTX *_mem_save_credential_0; TALLOC_CTX *_mem_save_return_authenticator_0; - TALLOC_CTX *_mem_save_change_log_entry_0; TALLOC_CTX *_mem_save_delta_enum_array_0; + TALLOC_CTX *_mem_save_delta_enum_array_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -11348,7 +11542,13 @@ static enum ndr_err_code ndr_pull_netr_DatabaseRedo(struct ndr_pull *ndr, int fl } NDR_CHECK(ndr_check_string_terminator(ndr, ndr_get_array_length(ndr, &r->in.computername), sizeof(uint16_t))); NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->in.computername, ndr_get_array_length(ndr, &r->in.computername), sizeof(uint16_t), CH_UTF16)); - NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, &r->in.credential)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.credential); + } + _mem_save_credential_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.credential, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.credential)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_credential_0, LIBNDR_FLAG_REF_ALLOC); if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { NDR_PULL_ALLOC(ndr, r->in.return_authenticator); } @@ -11356,28 +11556,17 @@ static enum ndr_err_code ndr_pull_netr_DatabaseRedo(struct ndr_pull *ndr, int fl NDR_PULL_SET_MEM_CTX(ndr, r->in.return_authenticator, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_netr_Authenticator(ndr, NDR_SCALARS, r->in.return_authenticator)); NDR_PULL_SET_MEM_CTX(ndr, _mem_save_return_authenticator_0, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_change_log_entry)); - if (_ptr_change_log_entry) { - NDR_PULL_ALLOC(ndr, r->in.change_log_entry); - } else { - r->in.change_log_entry = NULL; - } - if (r->in.change_log_entry) { - _mem_save_change_log_entry_0 = NDR_PULL_GET_MEM_CTX(ndr); - NDR_PULL_SET_MEM_CTX(ndr, r->in.change_log_entry, 0); - NDR_CHECK(ndr_pull_array_size(ndr, &r->in.change_log_entry)); - NDR_PULL_ALLOC_N(ndr, r->in.change_log_entry, ndr_get_array_size(ndr, &r->in.change_log_entry)); - NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->in.change_log_entry, ndr_get_array_size(ndr, &r->in.change_log_entry))); - NDR_PULL_SET_MEM_CTX(ndr, _mem_save_change_log_entry_0, 0); + { + struct ndr_pull *_ndr_change_log_entry; + NDR_CHECK(ndr_pull_subcontext_start(ndr, &_ndr_change_log_entry, 4, r->in.change_log_entry_size)); + NDR_CHECK(ndr_pull_netr_ChangeLogEntry(_ndr_change_log_entry, NDR_SCALARS|NDR_BUFFERS, &r->in.change_log_entry)); + NDR_CHECK(ndr_pull_subcontext_end(ndr, _ndr_change_log_entry, 4, r->in.change_log_entry_size)); } NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->in.change_log_entry_size)); NDR_PULL_ALLOC(ndr, r->out.return_authenticator); *r->out.return_authenticator = *r->in.return_authenticator; NDR_PULL_ALLOC(ndr, r->out.delta_enum_array); ZERO_STRUCTP(r->out.delta_enum_array); - if (r->in.change_log_entry) { - NDR_CHECK(ndr_check_array_size(ndr, (void*)&r->in.change_log_entry, r->in.change_log_entry_size)); - } } if (flags & NDR_OUT) { if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { @@ -11392,7 +11581,18 @@ static enum ndr_err_code ndr_pull_netr_DatabaseRedo(struct ndr_pull *ndr, int fl } _mem_save_delta_enum_array_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.delta_enum_array, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.delta_enum_array)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_delta_enum_array)); + if (_ptr_delta_enum_array) { + NDR_PULL_ALLOC(ndr, *r->out.delta_enum_array); + } else { + *r->out.delta_enum_array = NULL; + } + if (*r->out.delta_enum_array) { + _mem_save_delta_enum_array_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.delta_enum_array, 0); + NDR_CHECK(ndr_pull_netr_DELTA_ENUM_ARRAY(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.delta_enum_array)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_delta_enum_array_1, 0); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_delta_enum_array_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } @@ -11411,18 +11611,16 @@ _PUBLIC_ void ndr_print_netr_DatabaseRedo(struct ndr_print *ndr, const char *nam ndr->depth++; ndr_print_string(ndr, "logon_server", r->in.logon_server); ndr_print_string(ndr, "computername", r->in.computername); - ndr_print_netr_Authenticator(ndr, "credential", &r->in.credential); - ndr_print_ptr(ndr, "return_authenticator", r->in.return_authenticator); + ndr_print_ptr(ndr, "credential", r->in.credential); ndr->depth++; - ndr_print_netr_Authenticator(ndr, "return_authenticator", r->in.return_authenticator); + ndr_print_netr_Authenticator(ndr, "credential", r->in.credential); ndr->depth--; - ndr_print_ptr(ndr, "change_log_entry", r->in.change_log_entry); + ndr_print_ptr(ndr, "return_authenticator", r->in.return_authenticator); ndr->depth++; - if (r->in.change_log_entry) { - ndr_print_array_uint8(ndr, "change_log_entry", r->in.change_log_entry, r->in.change_log_entry_size); - } + ndr_print_netr_Authenticator(ndr, "return_authenticator", r->in.return_authenticator); ndr->depth--; - ndr_print_uint32(ndr, "change_log_entry_size", r->in.change_log_entry_size); + ndr_print_netr_ChangeLogEntry(ndr, "change_log_entry", &r->in.change_log_entry); + ndr_print_uint32(ndr, "change_log_entry_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?ndr_size_netr_ChangeLogEntry(&r->in.change_log_entry, ndr->flags):r->in.change_log_entry_size); ndr->depth--; } if (flags & NDR_OUT) { @@ -11434,7 +11632,12 @@ _PUBLIC_ void ndr_print_netr_DatabaseRedo(struct ndr_print *ndr, const char *nam ndr->depth--; ndr_print_ptr(ndr, "delta_enum_array", r->out.delta_enum_array); ndr->depth++; - ndr_print_netr_DELTA_ENUM_ARRAY(ndr, "delta_enum_array", r->out.delta_enum_array); + ndr_print_ptr(ndr, "delta_enum_array", *r->out.delta_enum_array); + ndr->depth++; + if (*r->out.delta_enum_array) { + ndr_print_netr_DELTA_ENUM_ARRAY(ndr, "delta_enum_array", *r->out.delta_enum_array); + } + ndr->depth--; ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; diff --git a/source3/librpc/gen_ndr/ndr_netlogon.h b/source3/librpc/gen_ndr/ndr_netlogon.h index 8561a5b5ca..be20448636 100644 --- a/source3/librpc/gen_ndr/ndr_netlogon.h +++ b/source3/librpc/gen_ndr/ndr_netlogon.h @@ -6,6 +6,7 @@ #ifndef _HEADER_NDR_netlogon #define _HEADER_NDR_netlogon +#include "../librpc/ndr/ndr_netlogon.h" #define NDR_NETLOGON_UUID "12345678-1234-abcd-ef00-01234567cffb" #define NDR_NETLOGON_VERSION 1.0 #define NDR_NETLOGON_NAME "netlogon" @@ -190,6 +191,12 @@ void ndr_print_netr_CONTROL_QUERY_INFORMATION(struct ndr_print *ndr, const char void ndr_print_netr_LogonControlCode(struct ndr_print *ndr, const char *name, enum netr_LogonControlCode r); void ndr_print_netr_CONTROL_DATA_INFORMATION(struct ndr_print *ndr, const char *name, const union netr_CONTROL_DATA_INFORMATION *r); void ndr_print_netr_NegotiateFlags(struct ndr_print *ndr, const char *name, uint32_t r); +void ndr_print_netr_ChangeLogFlags(struct ndr_print *ndr, const char *name, uint16_t r); +void ndr_print_netr_ChangeLogObject(struct ndr_print *ndr, const char *name, const union netr_ChangeLogObject *r); +enum ndr_err_code ndr_push_netr_ChangeLogEntry(struct ndr_push *ndr, int ndr_flags, const struct netr_ChangeLogEntry *r); +enum ndr_err_code ndr_pull_netr_ChangeLogEntry(struct ndr_pull *ndr, int ndr_flags, struct netr_ChangeLogEntry *r); +void ndr_print_netr_ChangeLogEntry(struct ndr_print *ndr, const char *name, const struct netr_ChangeLogEntry *r); +size_t ndr_size_netr_ChangeLogEntry(const struct netr_ChangeLogEntry *r, int flags); void ndr_print_netr_Blob(struct ndr_print *ndr, const char *name, const struct netr_Blob *r); void ndr_print_netr_DsRGetDCName_flags(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_netr_DsRGetDCNameInfo_AddressType(struct ndr_print *ndr, const char *name, enum netr_DsRGetDCNameInfo_AddressType r); diff --git a/source3/librpc/gen_ndr/ndr_samr.c b/source3/librpc/gen_ndr/ndr_samr.c index 10055aef37..e1b8fd17f9 100644 --- a/source3/librpc/gen_ndr/ndr_samr.c +++ b/source3/librpc/gen_ndr/ndr_samr.c @@ -9815,8 +9815,11 @@ static enum ndr_err_code ndr_push_samr_QueryUserInfo2(struct ndr_push *ndr, int if (r->out.info == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_set_switch_value(ndr, r->out.info, r->in.level)); - NDR_CHECK(ndr_push_samr_UserInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.info)); + if (*r->out.info) { + NDR_CHECK(ndr_push_set_switch_value(ndr, *r->out.info, r->in.level)); + NDR_CHECK(ndr_push_samr_UserInfo(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.info)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -9824,8 +9827,10 @@ static enum ndr_err_code ndr_push_samr_QueryUserInfo2(struct ndr_push *ndr, int static enum ndr_err_code ndr_pull_samr_QueryUserInfo2(struct ndr_pull *ndr, int flags, struct samr_QueryUserInfo2 *r) { + uint32_t _ptr_info; TALLOC_CTX *_mem_save_user_handle_0; TALLOC_CTX *_mem_save_info_0; + TALLOC_CTX *_mem_save_info_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -9846,8 +9851,19 @@ static enum ndr_err_code ndr_pull_samr_QueryUserInfo2(struct ndr_pull *ndr, int } _mem_save_info_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.info, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_set_switch_value(ndr, r->out.info, r->in.level)); - NDR_CHECK(ndr_pull_samr_UserInfo(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.info)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_info)); + if (_ptr_info) { + NDR_PULL_ALLOC(ndr, *r->out.info); + } else { + *r->out.info = NULL; + } + if (*r->out.info) { + _mem_save_info_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.info, 0); + NDR_CHECK(ndr_pull_set_switch_value(ndr, *r->out.info, r->in.level)); + NDR_CHECK(ndr_pull_samr_UserInfo(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.info)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_1, 0); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_info_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } @@ -9876,8 +9892,13 @@ _PUBLIC_ void ndr_print_samr_QueryUserInfo2(struct ndr_print *ndr, const char *n ndr->depth++; ndr_print_ptr(ndr, "info", r->out.info); ndr->depth++; - ndr_print_set_switch_value(ndr, r->out.info, r->in.level); - ndr_print_samr_UserInfo(ndr, "info", r->out.info); + ndr_print_ptr(ndr, "info", *r->out.info); + ndr->depth++; + if (*r->out.info) { + ndr_print_set_switch_value(ndr, *r->out.info, r->in.level); + ndr_print_samr_UserInfo(ndr, "info", *r->out.info); + } + ndr->depth--; ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; @@ -11886,7 +11907,10 @@ static enum ndr_err_code ndr_push_samr_RidToSid(struct ndr_push *ndr, int flags, if (r->out.sid == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid)); + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.sid)); + if (*r->out.sid) { + NDR_CHECK(ndr_push_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.sid)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -11894,8 +11918,10 @@ static enum ndr_err_code ndr_push_samr_RidToSid(struct ndr_push *ndr, int flags, static enum ndr_err_code ndr_pull_samr_RidToSid(struct ndr_pull *ndr, int flags, struct samr_RidToSid *r) { + uint32_t _ptr_sid; TALLOC_CTX *_mem_save_domain_handle_0; TALLOC_CTX *_mem_save_sid_0; + TALLOC_CTX *_mem_save_sid_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); @@ -11916,7 +11942,18 @@ static enum ndr_err_code ndr_pull_samr_RidToSid(struct ndr_pull *ndr, int flags, } _mem_save_sid_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.sid, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.sid)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_sid)); + if (_ptr_sid) { + NDR_PULL_ALLOC(ndr, *r->out.sid); + } else { + *r->out.sid = NULL; + } + if (*r->out.sid) { + _mem_save_sid_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.sid, 0); + NDR_CHECK(ndr_pull_dom_sid2(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.sid)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_1, 0); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_sid_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } @@ -11945,7 +11982,12 @@ _PUBLIC_ void ndr_print_samr_RidToSid(struct ndr_print *ndr, const char *name, i ndr->depth++; ndr_print_ptr(ndr, "sid", r->out.sid); ndr->depth++; - ndr_print_dom_sid2(ndr, "sid", r->out.sid); + ndr_print_ptr(ndr, "sid", *r->out.sid); + ndr->depth++; + if (*r->out.sid) { + ndr_print_dom_sid2(ndr, "sid", *r->out.sid); + } + ndr->depth--; ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; @@ -12049,15 +12091,21 @@ static enum ndr_err_code ndr_push_samr_ValidatePassword(struct ndr_push *ndr, in { if (flags & NDR_IN) { NDR_CHECK(ndr_push_samr_ValidatePasswordLevel(ndr, NDR_SCALARS, r->in.level)); - NDR_CHECK(ndr_push_set_switch_value(ndr, &r->in.req, r->in.level)); - NDR_CHECK(ndr_push_samr_ValidatePasswordReq(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.req)); + if (r->in.req == NULL) { + return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); + } + NDR_CHECK(ndr_push_set_switch_value(ndr, r->in.req, r->in.level)); + NDR_CHECK(ndr_push_samr_ValidatePasswordReq(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.req)); } if (flags & NDR_OUT) { if (r->out.rep == NULL) { return ndr_push_error(ndr, NDR_ERR_INVALID_POINTER, "NULL [ref] pointer"); } - NDR_CHECK(ndr_push_set_switch_value(ndr, r->out.rep, r->in.level)); - NDR_CHECK(ndr_push_samr_ValidatePasswordRep(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.rep)); + NDR_CHECK(ndr_push_unique_ptr(ndr, *r->out.rep)); + if (*r->out.rep) { + NDR_CHECK(ndr_push_set_switch_value(ndr, *r->out.rep, r->in.level)); + NDR_CHECK(ndr_push_samr_ValidatePasswordRep(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.rep)); + } NDR_CHECK(ndr_push_NTSTATUS(ndr, NDR_SCALARS, r->out.result)); } return NDR_ERR_SUCCESS; @@ -12065,13 +12113,22 @@ static enum ndr_err_code ndr_push_samr_ValidatePassword(struct ndr_push *ndr, in static enum ndr_err_code ndr_pull_samr_ValidatePassword(struct ndr_pull *ndr, int flags, struct samr_ValidatePassword *r) { + uint32_t _ptr_rep; + TALLOC_CTX *_mem_save_req_0; TALLOC_CTX *_mem_save_rep_0; + TALLOC_CTX *_mem_save_rep_1; if (flags & NDR_IN) { ZERO_STRUCT(r->out); NDR_CHECK(ndr_pull_samr_ValidatePasswordLevel(ndr, NDR_SCALARS, &r->in.level)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->in.req, r->in.level)); - NDR_CHECK(ndr_pull_samr_ValidatePasswordReq(ndr, NDR_SCALARS|NDR_BUFFERS, &r->in.req)); + if (ndr->flags & LIBNDR_FLAG_REF_ALLOC) { + NDR_PULL_ALLOC(ndr, r->in.req); + } + _mem_save_req_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->in.req, LIBNDR_FLAG_REF_ALLOC); + NDR_CHECK(ndr_pull_set_switch_value(ndr, r->in.req, r->in.level)); + NDR_CHECK(ndr_pull_samr_ValidatePasswordReq(ndr, NDR_SCALARS|NDR_BUFFERS, r->in.req)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_req_0, LIBNDR_FLAG_REF_ALLOC); NDR_PULL_ALLOC(ndr, r->out.rep); ZERO_STRUCTP(r->out.rep); } @@ -12081,8 +12138,19 @@ static enum ndr_err_code ndr_pull_samr_ValidatePassword(struct ndr_pull *ndr, in } _mem_save_rep_0 = NDR_PULL_GET_MEM_CTX(ndr); NDR_PULL_SET_MEM_CTX(ndr, r->out.rep, LIBNDR_FLAG_REF_ALLOC); - NDR_CHECK(ndr_pull_set_switch_value(ndr, r->out.rep, r->in.level)); - NDR_CHECK(ndr_pull_samr_ValidatePasswordRep(ndr, NDR_SCALARS|NDR_BUFFERS, r->out.rep)); + NDR_CHECK(ndr_pull_generic_ptr(ndr, &_ptr_rep)); + if (_ptr_rep) { + NDR_PULL_ALLOC(ndr, *r->out.rep); + } else { + *r->out.rep = NULL; + } + if (*r->out.rep) { + _mem_save_rep_1 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, *r->out.rep, 0); + NDR_CHECK(ndr_pull_set_switch_value(ndr, *r->out.rep, r->in.level)); + NDR_CHECK(ndr_pull_samr_ValidatePasswordRep(ndr, NDR_SCALARS|NDR_BUFFERS, *r->out.rep)); + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_rep_1, 0); + } NDR_PULL_SET_MEM_CTX(ndr, _mem_save_rep_0, LIBNDR_FLAG_REF_ALLOC); NDR_CHECK(ndr_pull_NTSTATUS(ndr, NDR_SCALARS, &r->out.result)); } @@ -12100,8 +12168,11 @@ _PUBLIC_ void ndr_print_samr_ValidatePassword(struct ndr_print *ndr, const char ndr_print_struct(ndr, "in", "samr_ValidatePassword"); ndr->depth++; ndr_print_samr_ValidatePasswordLevel(ndr, "level", r->in.level); - ndr_print_set_switch_value(ndr, &r->in.req, r->in.level); - ndr_print_samr_ValidatePasswordReq(ndr, "req", &r->in.req); + ndr_print_ptr(ndr, "req", r->in.req); + ndr->depth++; + ndr_print_set_switch_value(ndr, r->in.req, r->in.level); + ndr_print_samr_ValidatePasswordReq(ndr, "req", r->in.req); + ndr->depth--; ndr->depth--; } if (flags & NDR_OUT) { @@ -12109,8 +12180,13 @@ _PUBLIC_ void ndr_print_samr_ValidatePassword(struct ndr_print *ndr, const char ndr->depth++; ndr_print_ptr(ndr, "rep", r->out.rep); ndr->depth++; - ndr_print_set_switch_value(ndr, r->out.rep, r->in.level); - ndr_print_samr_ValidatePasswordRep(ndr, "rep", r->out.rep); + ndr_print_ptr(ndr, "rep", *r->out.rep); + ndr->depth++; + if (*r->out.rep) { + ndr_print_set_switch_value(ndr, *r->out.rep, r->in.level); + ndr_print_samr_ValidatePasswordRep(ndr, "rep", *r->out.rep); + } + ndr->depth--; ndr->depth--; ndr_print_NTSTATUS(ndr, "result", r->out.result); ndr->depth--; diff --git a/source3/librpc/gen_ndr/ndr_security.c b/source3/librpc/gen_ndr/ndr_security.c index de899241ab..108f2f689c 100644 --- a/source3/librpc/gen_ndr/ndr_security.c +++ b/source3/librpc/gen_ndr/ndr_security.c @@ -4,13 +4,14 @@ #include "librpc/gen_ndr/ndr_security.h" #include "librpc/gen_ndr/ndr_misc.h" -static enum ndr_err_code ndr_push_security_ace_flags(struct ndr_push *ndr, int ndr_flags, uint8_t r) +#include "librpc/gen_ndr/ndr_dom_sid.h" +_PUBLIC_ enum ndr_err_code ndr_push_security_ace_flags(struct ndr_push *ndr, int ndr_flags, uint8_t r) { NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r) +_PUBLIC_ enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r) { uint8_t v; NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); @@ -33,13 +34,13 @@ _PUBLIC_ void ndr_print_security_ace_flags(struct ndr_print *ndr, const char *na ndr->depth--; } -static enum ndr_err_code ndr_push_security_ace_type(struct ndr_push *ndr, int ndr_flags, enum security_ace_type r) +_PUBLIC_ enum ndr_err_code ndr_push_security_ace_type(struct ndr_push *ndr, int ndr_flags, enum security_ace_type r) { NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r) +_PUBLIC_ enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r) { uint8_t v; NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); @@ -278,7 +279,7 @@ _PUBLIC_ void ndr_print_security_ace_object(struct ndr_print *ndr, const char *n ndr->depth--; } -static enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, int ndr_flags, const union security_ace_object_ctr *r) +_PUBLIC_ enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, int ndr_flags, const union security_ace_object_ctr *r) { if (ndr_flags & NDR_SCALARS) { int level = ndr_push_get_switch_value(ndr, r); @@ -331,7 +332,7 @@ static enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, return NDR_ERR_SUCCESS; } -static enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r) +_PUBLIC_ enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r) { int level; level = ndr_pull_get_switch_value(ndr, r); @@ -431,25 +432,6 @@ _PUBLIC_ enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, int ndr_f return NDR_ERR_SUCCESS; } -_PUBLIC_ enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r) -{ - if (ndr_flags & NDR_SCALARS) { - NDR_CHECK(ndr_pull_align(ndr, 4)); - NDR_CHECK(ndr_pull_security_ace_type(ndr, NDR_SCALARS, &r->type)); - NDR_CHECK(ndr_pull_security_ace_flags(ndr, NDR_SCALARS, &r->flags)); - NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->size)); - NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->access_mask)); - NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, r->type)); - NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_SCALARS, &r->object)); - NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_SCALARS, &r->trustee)); - } - if (ndr_flags & NDR_BUFFERS) { - NDR_CHECK(ndr_pull_security_ace_object_ctr(ndr, NDR_BUFFERS, &r->object)); - NDR_CHECK(ndr_pull_dom_sid(ndr, NDR_BUFFERS, &r->trustee)); - } - return NDR_ERR_SUCCESS; -} - _PUBLIC_ void ndr_print_security_ace(struct ndr_print *ndr, const char *name, const struct security_ace *r) { ndr_print_struct(ndr, name, "security_ace"); diff --git a/source3/librpc/gen_ndr/ndr_security.h b/source3/librpc/gen_ndr/ndr_security.h index 7a2ff74309..bddf1bd2b7 100644 --- a/source3/librpc/gen_ndr/ndr_security.h +++ b/source3/librpc/gen_ndr/ndr_security.h @@ -6,13 +6,20 @@ #ifndef _HEADER_NDR_security #define _HEADER_NDR_security +#include "librpc/gen_ndr/ndr_dom_sid.h" #define NDR_SECURITY_CALL_COUNT (0) +enum ndr_err_code ndr_push_security_ace_flags(struct ndr_push *ndr, int ndr_flags, uint8_t r); +enum ndr_err_code ndr_pull_security_ace_flags(struct ndr_pull *ndr, int ndr_flags, uint8_t *r); void ndr_print_security_ace_flags(struct ndr_print *ndr, const char *name, uint8_t r); +enum ndr_err_code ndr_push_security_ace_type(struct ndr_push *ndr, int ndr_flags, enum security_ace_type r); +enum ndr_err_code ndr_pull_security_ace_type(struct ndr_pull *ndr, int ndr_flags, enum security_ace_type *r); void ndr_print_security_ace_type(struct ndr_print *ndr, const char *name, enum security_ace_type r); void ndr_print_security_ace_object_flags(struct ndr_print *ndr, const char *name, uint32_t r); void ndr_print_security_ace_object_type(struct ndr_print *ndr, const char *name, const union security_ace_object_type *r); void ndr_print_security_ace_object_inherited_type(struct ndr_print *ndr, const char *name, const union security_ace_object_inherited_type *r); void ndr_print_security_ace_object(struct ndr_print *ndr, const char *name, const struct security_ace_object *r); +enum ndr_err_code ndr_push_security_ace_object_ctr(struct ndr_push *ndr, int ndr_flags, const union security_ace_object_ctr *r); +enum ndr_err_code ndr_pull_security_ace_object_ctr(struct ndr_pull *ndr, int ndr_flags, union security_ace_object_ctr *r); void ndr_print_security_ace_object_ctr(struct ndr_print *ndr, const char *name, const union security_ace_object_ctr *r); enum ndr_err_code ndr_push_security_ace(struct ndr_push *ndr, int ndr_flags, const struct security_ace *r); enum ndr_err_code ndr_pull_security_ace(struct ndr_pull *ndr, int ndr_flags, struct security_ace *r); diff --git a/source3/librpc/gen_ndr/netlogon.h b/source3/librpc/gen_ndr/netlogon.h index 9f5d28a95f..51cca4083b 100644 --- a/source3/librpc/gen_ndr/netlogon.h +++ b/source3/librpc/gen_ndr/netlogon.h @@ -7,11 +7,14 @@ #include "librpc/gen_ndr/samr.h" #include "librpc/gen_ndr/security.h" #include "librpc/gen_ndr/nbt.h" +#define netr_DeltaEnum8Bit netr_DeltaEnum #ifndef _HEADER_netlogon #define _HEADER_netlogon #define DSGETDC_VALID_FLAGS ( (DS_FORCE_REDISCOVERY|DS_DIRECTORY_SERVICE_REQUIRED|DS_DIRECTORY_SERVICE_PREFERRED|DS_GC_SERVER_REQUIRED|DS_PDC_REQUIRED|DS_BACKGROUND_ONLY|DS_IP_REQUIRED|DS_KDC_REQUIRED|DS_TIMESERV_REQUIRED|DS_WRITABLE_REQUIRED|DS_GOOD_TIMESERV_PREFERRED|DS_AVOID_SELF|DS_ONLY_LDAP_NEEDED|DS_IS_FLAT_NAME|DS_IS_DNS_NAME|DS_RETURN_FLAT_NAME|DS_RETURN_DNS_NAME) ) #define DS_GFTI_UPDATE_TDO ( 0x1 ) +enum netr_DeltaEnum8Bit; + struct netr_UasInfo { const char *account_name;/* [unique,charset(UTF16)] */ uint32_t priv; @@ -324,7 +327,7 @@ struct netr_DELTA_USER { uint8_t lm_password_present; uint8_t password_expired; struct lsa_String comment; - struct lsa_String parameters; + struct lsa_BinaryString parameters; uint16_t country_code; uint16_t code_page; struct netr_USER_PRIVATE_INFO user_private_info; @@ -712,6 +715,28 @@ union netr_CONTROL_DATA_INFORMATION { #define NETLOGON_NEG_AUTHENTICATED_RPC_LSASS ( 0x20000000 ) #define NETLOGON_NEG_SCHANNEL ( 0x40000000 ) +/* bitmap netr_ChangeLogFlags */ +#define NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED ( 0x0001 ) +#define NETR_CHANGELOG_CHANGED_PASSWORD ( 0x0002 ) +#define NETR_CHANGELOG_SID_INCLUDED ( 0x0004 ) +#define NETR_CHANGELOG_NAME_INCLUDED ( 0x0008 ) +#define NETR_CHANGELOG_FIRST_PROMOTION_OBJ ( 0x0010 ) + +union netr_ChangeLogObject { + struct dom_sid object_sid;/* [case(NETR_CHANGELOG_SID_INCLUDED)] */ + const char * object_name;/* [flag(LIBNDR_FLAG_STR_NULLTERM),case(NETR_CHANGELOG_NAME_INCLUDED)] */ +}/* [nodiscriminant] */; + +struct netr_ChangeLogEntry { + uint32_t serial_number1; + uint32_t serial_number2; + uint32_t object_rid; + uint16_t flags; + enum netr_SamDatabaseID8Bit db_index; + enum netr_DeltaEnum8Bit delta_type; + union netr_ChangeLogObject object;/* [switch_is(flags&(NETR_CHANGELOG_SID_INCLUDED|NETR_CHANGELOG_NAME_INCLUDED))] */ +}/* [gensize,public] */; + struct netr_Blob { uint32_t length; uint8_t *data;/* [unique,size_is(length)] */ @@ -1251,14 +1276,14 @@ struct netr_DatabaseRedo { struct { const char *logon_server;/* [charset(UTF16)] */ const char *computername;/* [charset(UTF16)] */ - struct netr_Authenticator credential; - uint8_t *change_log_entry;/* [unique,size_is(change_log_entry_size)] */ - uint32_t change_log_entry_size; + struct netr_Authenticator *credential;/* [ref] */ + struct netr_ChangeLogEntry change_log_entry;/* [subcontext_size(change_log_entry_size),subcontext(4)] */ + uint32_t change_log_entry_size;/* [value(ndr_size_netr_ChangeLogEntry(&change_log_entry,ndr->flags))] */ struct netr_Authenticator *return_authenticator;/* [ref] */ } in; struct { - struct netr_DELTA_ENUM_ARRAY *delta_enum_array;/* [ref] */ + struct netr_DELTA_ENUM_ARRAY **delta_enum_array;/* [ref] */ struct netr_Authenticator *return_authenticator;/* [ref] */ NTSTATUS result; } out; diff --git a/source3/librpc/gen_ndr/samr.h b/source3/librpc/gen_ndr/samr.h index 62f6bf8de6..d900c29d5e 100644 --- a/source3/librpc/gen_ndr/samr.h +++ b/source3/librpc/gen_ndr/samr.h @@ -8,8 +8,31 @@ #ifndef _HEADER_samr #define _HEADER_samr -#define MAX_SAM_ENTRIES_W2K ( 0x400 ) -#define MAX_SAM_ENTRIES_W95 ( 50 ) +#define SAMR_ACCESS_ALL_ACCESS ( 0x0000003F ) +#define GENERIC_RIGHTS_SAM_ALL_ACCESS ( (STANDARD_RIGHTS_REQUIRED_ACCESS|SAMR_ACCESS_ALL_ACCESS) ) +#define GENERIC_RIGHTS_SAM_READ ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_ACCESS_ENUM_DOMAINS) ) +#define GENERIC_RIGHTS_SAM_WRITE ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_ACCESS_CREATE_DOMAIN|SAMR_ACCESS_INITIALIZE_SERVER|SAMR_ACCESS_SHUTDOWN_SERVER) ) +#define GENERIC_RIGHTS_SAM_EXECUTE ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_ACCESS_OPEN_DOMAIN|SAMR_ACCESS_CONNECT_TO_SERVER) ) +#define SAMR_USER_ACCESS_ALL_ACCESS ( 0x000007FF ) +#define GENERIC_RIGHTS_USER_ALL_ACCESS ( (STANDARD_RIGHTS_REQUIRED_ACCESS|SAMR_USER_ACCESS_ALL_ACCESS) ) +#define GENERIC_RIGHTS_USER_READ ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP|SAMR_USER_ACCESS_GET_GROUPS|SAMR_USER_ACCESS_GET_ATTRIBUTES|SAMR_USER_ACCESS_GET_LOGONINFO|SAMR_USER_ACCESS_GET_LOCALE) ) +#define GENERIC_RIGHTS_USER_WRITE ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_USER_ACCESS_CHANGE_PASSWORD|SAMR_USER_ACCESS_SET_LOC_COM|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP) ) +#define GENERIC_RIGHTS_USER_EXECUTE ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_USER_ACCESS_CHANGE_PASSWORD|SAMR_USER_ACCESS_GET_NAME_ETC) ) +#define SAMR_DOMAIN_ACCESS_ALL_ACCESS ( 0x000007FF ) +#define GENERIC_RIGHTS_DOMAIN_ALL_ACCESS ( (STANDARD_RIGHTS_REQUIRED_ACCESS|SAMR_DOMAIN_ACCESS_ALL_ACCESS) ) +#define GENERIC_RIGHTS_DOMAIN_READ ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS|SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2) ) +#define GENERIC_RIGHTS_DOMAIN_WRITE ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_DOMAIN_ACCESS_SET_INFO_3|SAMR_DOMAIN_ACCESS_CREATE_ALIAS|SAMR_DOMAIN_ACCESS_CREATE_GROUP|SAMR_DOMAIN_ACCESS_CREATE_USER|SAMR_DOMAIN_ACCESS_SET_INFO_2|SAMR_DOMAIN_ACCESS_SET_INFO_1) ) +#define GENERIC_RIGHTS_DOMAIN_EXECUTE ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT|SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS|SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1) ) +#define SAMR_GROUP_ACCESS_ALL_ACCESS ( 0x0000001F ) +#define GENERIC_RIGHTS_GROUP_ALL_ACCESS ( (STANDARD_RIGHTS_REQUIRED_ACCESS|SAMR_GROUP_ACCESS_ALL_ACCESS) ) +#define GENERIC_RIGHTS_GROUP_READ ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_GROUP_ACCESS_GET_MEMBERS) ) +#define GENERIC_RIGHTS_GROUP_WRITE ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_GROUP_ACCESS_REMOVE_MEMBER|SAMR_GROUP_ACCESS_ADD_MEMBER|SAMR_GROUP_ACCESS_SET_INFO) ) +#define GENERIC_RIGHTS_GROUP_EXECUTE ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_GROUP_ACCESS_LOOKUP_INFO) ) +#define SAMR_ALIAS_ACCESS_ALL_ACCESS ( 0x0000001F ) +#define GENERIC_RIGHTS_ALIAS_ALL_ACCESS ( (STANDARD_RIGHTS_REQUIRED_ACCESS|SAMR_ALIAS_ACCESS_ALL_ACCESS) ) +#define GENERIC_RIGHTS_ALIAS_READ ( (STANDARD_RIGHTS_READ_ACCESS|SAMR_ALIAS_ACCESS_GET_MEMBERS) ) +#define GENERIC_RIGHTS_ALIAS_WRITE ( (STANDARD_RIGHTS_WRITE_ACCESS|SAMR_ALIAS_ACCESS_REMOVE_MEMBER|SAMR_ALIAS_ACCESS_ADD_MEMBER|SAMR_ALIAS_ACCESS_SET_INFO) ) +#define GENERIC_RIGHTS_ALIAS_EXECUTE ( (STANDARD_RIGHTS_EXECUTE_ACCESS|SAMR_ALIAS_ACCESS_LOOKUP_INFO) ) #define SAMR_ENUM_USERS_MULTIPLIER ( 54 ) #define PASS_MUST_CHANGE_AT_NEXT_LOGON ( 0x01 ) #define PASS_DONT_CHANGE_AT_NEXT_LOGON ( 0x00 ) @@ -1440,7 +1463,7 @@ struct samr_QueryUserInfo2 { } in; struct { - union samr_UserInfo *info;/* [ref,switch_is(level)] */ + union samr_UserInfo **info;/* [ref,switch_is(level)] */ NTSTATUS result; } out; @@ -1722,7 +1745,7 @@ struct samr_RidToSid { } in; struct { - struct dom_sid2 *sid;/* [ref] */ + struct dom_sid2 **sid;/* [ref] */ NTSTATUS result; } out; @@ -1746,11 +1769,11 @@ struct samr_SetDsrmPassword { struct samr_ValidatePassword { struct { enum samr_ValidatePasswordLevel level; - union samr_ValidatePasswordReq req;/* [switch_is(level)] */ + union samr_ValidatePasswordReq *req;/* [ref,switch_is(level)] */ } in; struct { - union samr_ValidatePasswordRep *rep;/* [ref,switch_is(level)] */ + union samr_ValidatePasswordRep **rep;/* [ref,switch_is(level)] */ NTSTATUS result; } out; diff --git a/source3/librpc/gen_ndr/security.h b/source3/librpc/gen_ndr/security.h index 5b77d76b50..fe23347fdf 100644 --- a/source3/librpc/gen_ndr/security.h +++ b/source3/librpc/gen_ndr/security.h @@ -3,9 +3,7 @@ #include <stdint.h> #include "librpc/gen_ndr/misc.h" -#define dom_sid2 dom_sid -#define dom_sid28 dom_sid -#define dom_sid0 dom_sid +#include "librpc/gen_ndr/dom_sid.h" #ifndef _HEADER_security #define _HEADER_security @@ -68,6 +66,12 @@ #define SEC_RIGHTS_DIR_WRITE ( SEC_RIGHTS_FILE_WRITE ) #define SEC_RIGHTS_DIR_EXECUTE ( SEC_RIGHTS_FILE_EXECUTE ) #define SEC_RIGHTS_DIR_ALL ( SEC_RIGHTS_FILE_ALL ) +#define STANDARD_RIGHTS_ALL_ACCESS ( SEC_STD_ALL ) +#define STANDARD_RIGHTS_MODIFY_ACCESS ( SEC_STD_READ_CONTROL ) +#define STANDARD_RIGHTS_EXECUTE_ACCESS ( SEC_STD_READ_CONTROL ) +#define STANDARD_RIGHTS_READ_ACCESS ( SEC_STD_READ_CONTROL ) +#define STANDARD_RIGHTS_WRITE_ACCESS ( (SEC_STD_WRITE_OWNER|SEC_STD_WRITE_DAC|SEC_STD_DELETE) ) +#define STANDARD_RIGHTS_REQUIRED_ACCESS ( (SEC_STD_DELETE|SEC_STD_READ_CONTROL|SEC_STD_WRITE_DAC|SEC_STD_WRITE_OWNER) ) #define SID_NULL ( "S-1-0-0" ) #define NAME_WORLD ( "WORLD" ) #define SID_WORLD_DOMAIN ( "S-1-1" ) @@ -239,7 +243,7 @@ struct security_ace_object { union security_ace_object_ctr { struct security_ace_object object;/* [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] */ -}/* [nodiscriminant] */; +}/* [public,nodiscriminant] */; struct security_ace { enum security_ace_type type; @@ -248,7 +252,7 @@ struct security_ace { uint32_t access_mask; union security_ace_object_ctr object;/* [switch_is(type)] */ struct dom_sid trustee; -}/* [gensize,public,nosize] */; +}/* [gensize,public,nopull,nosize] */; enum security_acl_revision #ifndef USE_UINT_ENUMS diff --git a/source3/librpc/gen_ndr/srv_netlogon.c b/source3/librpc/gen_ndr/srv_netlogon.c index b740e7b333..9546b2551b 100644 --- a/source3/librpc/gen_ndr/srv_netlogon.c +++ b/source3/librpc/gen_ndr/srv_netlogon.c @@ -1454,7 +1454,7 @@ static bool api_netr_DatabaseRedo(pipes_struct *p) ZERO_STRUCT(r->out); r->out.return_authenticator = r->in.return_authenticator; - r->out.delta_enum_array = talloc_zero(r, struct netr_DELTA_ENUM_ARRAY); + r->out.delta_enum_array = talloc_zero(r, struct netr_DELTA_ENUM_ARRAY *); if (r->out.delta_enum_array == NULL) { talloc_free(r); return false; diff --git a/source3/librpc/gen_ndr/srv_samr.c b/source3/librpc/gen_ndr/srv_samr.c index e09c7a3faf..f4facd2914 100644 --- a/source3/librpc/gen_ndr/srv_samr.c +++ b/source3/librpc/gen_ndr/srv_samr.c @@ -3750,7 +3750,7 @@ static bool api_samr_QueryUserInfo2(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.info = talloc_zero(r, union samr_UserInfo); + r->out.info = talloc_zero(r, union samr_UserInfo *); if (r->out.info == NULL) { talloc_free(r); return false; @@ -5202,7 +5202,7 @@ static bool api_samr_RidToSid(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.sid = talloc_zero(r, struct dom_sid2); + r->out.sid = talloc_zero(r, struct dom_sid2 *); if (r->out.sid == NULL) { talloc_free(r); return false; @@ -5355,7 +5355,7 @@ static bool api_samr_ValidatePassword(pipes_struct *p) } ZERO_STRUCT(r->out); - r->out.rep = talloc_zero(r, union samr_ValidatePasswordRep); + r->out.rep = talloc_zero(r, union samr_ValidatePasswordRep *); if (r->out.rep == NULL) { talloc_free(r); return false; diff --git a/source3/librpc/idl/dom_sid.idl b/source3/librpc/idl/dom_sid.idl new file mode 100644 index 0000000000..c405c18726 --- /dev/null +++ b/source3/librpc/idl/dom_sid.idl @@ -0,0 +1,29 @@ +/* + use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really + just a dom sid, but with the sub_auths represented as a conformant + array. As with all in-structure conformant arrays, the array length + is placed before the start of the structure. That's what gives rise + to the extra num_auths elemenent. We don't want the Samba code to + have to bother with such esoteric NDR details, so its easier to just + define it as a dom_sid and use pidl magic to make it all work. It + just means you need to mark a sid as a "dom_sid2" in the IDL when you + know it is of the conformant array variety +*/ +cpp_quote("#define dom_sid2 dom_sid") + +/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ +cpp_quote("#define dom_sid28 dom_sid") + +/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */ +cpp_quote("#define dom_sid0 dom_sid") + +[ + pointer_default(unique) +] +interface dom_sid +{ + struct _dummy_domsid { + uint8 dummy; + }; +} + diff --git a/source3/librpc/ndr/ndr_sec.h b/source3/librpc/ndr/ndr_sec.h deleted file mode 100644 index 8034367223..0000000000 --- a/source3/librpc/ndr/ndr_sec.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __LIBRPC_NDR_NDR_SEC_H__ -#define __LIBRPC_NDR_NDR_SEC_H__ - -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) -/* This file was automatically generated by mkproto.pl. DO NOT EDIT */ - -#ifndef _PUBLIC_ -#define _PUBLIC_ -#endif - - -/* The following definitions come from librpc/ndr/ndr_sec_helper.c */ - -size_t ndr_size_dom_sid(const struct dom_sid *sid); -size_t ndr_length_dom_sid(const struct dom_sid *sid); -size_t ndr_size_security_ace(const struct security_ace *ace); -size_t ndr_size_security_acl(const struct security_acl *acl); -size_t ndr_size_security_descriptor(const struct security_descriptor *sd); -void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid); -void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid); -void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid); -char *dom_sid_string(TALLOC_CTX *mem_ctx, const struct dom_sid *sid); - -/* The following definitions come from librpc/ndr/ndr_sec.c */ - -enum ndr_err_code ndr_pull_dom_sid2(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid); -enum ndr_err_code ndr_push_dom_sid2(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid); -enum ndr_err_code ndr_pull_dom_sid28(struct ndr_pull *ndr, int ndr_flags, struct dom_sid *sid); -enum ndr_err_code ndr_push_dom_sid28(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *sid); -#undef _PRINTF_ATTRIBUTE -#define _PRINTF_ATTRIBUTE(a1, a2) - -#endif /* __LIBRPC_NDR_NDR_SEC_H__ */ - diff --git a/source3/librpc/ndr/ndr_sec_helper.c b/source3/librpc/ndr/ndr_sec_helper.c deleted file mode 100644 index 18d343799e..0000000000 --- a/source3/librpc/ndr/ndr_sec_helper.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - Unix SMB/CIFS implementation. - - fast routines for getting the wire size of security objects - - Copyright (C) Andrew Tridgell 2003 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - - -#include "includes.h" - -/* - return the wire size of a dom_sid -*/ -size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags) -{ - if (!sid) return 0; - return 8 + 4*sid->num_auths; -} - -size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags) -{ - struct dom_sid zero_sid; - - if (!sid) return 0; - - ZERO_STRUCT(zero_sid); - - if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) { - return 0; - } - - return 8 + 4*sid->num_auths; -} - -size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags) -{ - return ndr_size_dom_sid28(sid, flags); -} - -/* - return the wire size of a security_ace -*/ -size_t ndr_size_security_ace(const struct security_ace *ace, int flags) -{ - if (!ace) return 0; - return 8 + ndr_size_dom_sid(&ace->trustee, flags); -} - - -/* - return the wire size of a security_acl -*/ -size_t ndr_size_security_acl(const struct security_acl *acl, int flags) -{ - size_t ret; - int i; - if (!acl) return 0; - ret = 8; - for (i=0;i<acl->num_aces;i++) { - ret += ndr_size_security_ace(&acl->aces[i], flags); - } - return ret; -} - -/* - return the wire size of a security descriptor -*/ -size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags) -{ - size_t ret; - if (!sd) return 0; - - ret = 20; - ret += ndr_size_dom_sid(sd->owner_sid, flags); - ret += ndr_size_dom_sid(sd->group_sid, flags); - ret += ndr_size_security_acl(sd->dacl, flags); - ret += ndr_size_security_acl(sd->sacl, flags); - return ret; -} - -/* - print a dom_sid -*/ -void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) -{ - ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid)); -} - -void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) -{ - ndr_print_dom_sid(ndr, name, sid); -} - -void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) -{ - ndr_print_dom_sid(ndr, name, sid); -} - -void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) -{ - ndr_print_dom_sid(ndr, name, sid); -} - diff --git a/source3/librpc/ndr/sid.c b/source3/librpc/ndr/sid.c index ed27375de1..39b7e3cd59 100644 --- a/source3/librpc/ndr/sid.c +++ b/source3/librpc/ndr/sid.c @@ -21,6 +21,35 @@ #include "includes.h" +/* + return the wire size of a dom_sid +*/ +size_t ndr_size_dom_sid(const struct dom_sid *sid, int flags) +{ + if (!sid) return 0; + return 8 + 4*sid->num_auths; +} + +size_t ndr_size_dom_sid28(const struct dom_sid *sid, int flags) +{ + struct dom_sid zero_sid; + + if (!sid) return 0; + + ZERO_STRUCT(zero_sid); + + if (memcmp(&zero_sid, sid, sizeof(zero_sid)) == 0) { + return 0; + } + + return 8 + 4*sid->num_auths; +} + +size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags) +{ + return ndr_size_dom_sid28(sid, flags); +} + enum ndr_err_code ndr_push_dom_sid(struct ndr_push *ndr, int ndr_flags, const struct dom_sid *r) { uint32_t cntr_sub_auths_0; @@ -228,3 +257,27 @@ enum ndr_err_code ndr_push_dom_sid0(struct ndr_push *ndr, int ndr_flags, const s return ndr_push_dom_sid(ndr, ndr_flags, sid); } + +/* + print a dom_sid +*/ +void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) +{ + ndr->print(ndr, "%-25s: %s", name, dom_sid_string(ndr, sid)); +} + +void ndr_print_dom_sid2(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) +{ + ndr_print_dom_sid(ndr, name, sid); +} + +void ndr_print_dom_sid28(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) +{ + ndr_print_dom_sid(ndr, name, sid); +} + +void ndr_print_dom_sid0(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) +{ + ndr_print_dom_sid(ndr, name, sid); +} + diff --git a/source3/librpc/ndr/util.c b/source3/librpc/ndr/util.c index 457615ce22..b8221838fa 100644 --- a/source3/librpc/ndr/util.c +++ b/source3/librpc/ndr/util.c @@ -166,7 +166,7 @@ _PUBLIC_ void ndr_print_sockaddr_storage(struct ndr_print *ndr, const char *name ndr->print(ndr, "%-25s: %s", name, print_sockaddr(addr, sizeof(addr), ss)); } -void *global_loadparm; +void *global_iconv_convenience; void *cmdline_lp_ctx; struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx) { diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 6b4798e492..1588ae3efe 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -516,7 +516,7 @@ static DATA_BLOB cli_session_setup_blob_receive(struct cli_state *cli) p += clistr_pull(cli, cli->server_os, p, sizeof(fstring), -1, STR_TERMINATE); /* w2k with kerberos doesn't properly null terminate this field */ - len = smb_buflen(cli->inbuf) - PTR_DIFF(p, smb_buf(cli->inbuf)); + len = smb_bufrem(cli->inbuf, p); p += clistr_pull(cli, cli->server_type, p, sizeof(fstring), len, 0); return blob2; diff --git a/source3/libsmb/doserr.c b/source3/libsmb/doserr.c deleted file mode 100644 index 0cccae1e6a..0000000000 --- a/source3/libsmb/doserr.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Unix SMB/CIFS implementation. - * DOS error routines - * Copyright (C) Tim Potter 2002. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -/* DOS error codes. please read doserr.h */ - -#include "includes.h" - -typedef const struct { - const char *dos_errstr; - WERROR werror; -} werror_code_struct; - -typedef const struct { - WERROR werror; - const char *friendly_errstr; -} werror_str_struct; - -werror_code_struct dos_errs[] = -{ - { "WERR_OK", WERR_OK }, - { "WERR_GENERAL_FAILURE", WERR_GENERAL_FAILURE }, - { "WERR_BADFILE", WERR_BADFILE }, - { "WERR_ACCESS_DENIED", WERR_ACCESS_DENIED }, - { "WERR_BADFID", WERR_BADFID }, - { "WERR_BADFUNC", WERR_BADFUNC }, - { "WERR_INSUFFICIENT_BUFFER", WERR_INSUFFICIENT_BUFFER }, - { "WERR_SEM_TIMEOUT", WERR_SEM_TIMEOUT }, - { "WERR_NO_SUCH_SHARE", WERR_NO_SUCH_SHARE }, - { "WERR_FILE_EXISTS", WERR_FILE_EXISTS }, - { "WERR_INVALID_PARAM", WERR_INVALID_PARAM }, - { "WERR_NOT_SUPPORTED", WERR_NOT_SUPPORTED }, - { "WERR_BAD_PASSWORD", WERR_BAD_PASSWORD }, - { "WERR_NOMEM", WERR_NOMEM }, - { "WERR_INVALID_NAME", WERR_INVALID_NAME }, - { "WERR_UNKNOWN_LEVEL", WERR_UNKNOWN_LEVEL }, - { "WERR_OBJECT_PATH_INVALID", WERR_OBJECT_PATH_INVALID }, - { "WERR_NO_MORE_ITEMS", WERR_NO_MORE_ITEMS }, - { "WERR_MORE_DATA", WERR_MORE_DATA }, - { "WERR_UNKNOWN_PRINTER_DRIVER", WERR_UNKNOWN_PRINTER_DRIVER }, - { "WERR_INVALID_PRINTER_NAME", WERR_INVALID_PRINTER_NAME }, - { "WERR_PRINTER_ALREADY_EXISTS", WERR_PRINTER_ALREADY_EXISTS }, - { "WERR_INVALID_DATATYPE", WERR_INVALID_DATATYPE }, - { "WERR_INVALID_ENVIRONMENT", WERR_INVALID_ENVIRONMENT }, - { "WERR_INVALID_FORM_NAME", WERR_INVALID_FORM_NAME }, - { "WERR_INVALID_FORM_SIZE", WERR_INVALID_FORM_SIZE }, - { "WERR_BUF_TOO_SMALL", WERR_BUF_TOO_SMALL }, - { "WERR_JOB_NOT_FOUND", WERR_JOB_NOT_FOUND }, - { "WERR_DEST_NOT_FOUND", WERR_DEST_NOT_FOUND }, - { "WERR_GROUP_NOT_FOUND", WERR_GROUP_NOT_FOUND }, - { "WERR_USER_NOT_FOUND", WERR_USER_NOT_FOUND }, - { "WERR_NOT_LOCAL_DOMAIN", WERR_NOT_LOCAL_DOMAIN }, - { "WERR_USER_EXISTS", WERR_USER_EXISTS }, - { "WERR_REVISION_MISMATCH", WERR_REVISION_MISMATCH }, - { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS }, - { "WERR_NO_SUCH_LOGON_SESSION", WERR_NO_SUCH_LOGON_SESSION }, - { "WERR_USER_ALREADY_EXISTS", WERR_USER_ALREADY_EXISTS }, - { "WERR_NO_SUCH_USER", WERR_NO_SUCH_USER }, - { "WERR_GROUP_EXISTS", WERR_GROUP_EXISTS }, - { "WERR_MEMBER_IN_GROUP", WERR_MEMBER_IN_GROUP }, - { "WERR_USER_NOT_IN_GROUP", WERR_USER_NOT_IN_GROUP }, - { "WERR_PRINTER_DRIVER_IN_USE", WERR_PRINTER_DRIVER_IN_USE }, - { "WERR_STATUS_MORE_ENTRIES ", WERR_STATUS_MORE_ENTRIES }, - { "WERR_DFS_NO_SUCH_VOL", WERR_DFS_NO_SUCH_VOL }, - { "WERR_DFS_NO_SUCH_SHARE", WERR_DFS_NO_SUCH_SHARE }, - { "WERR_DFS_NO_SUCH_SERVER", WERR_DFS_NO_SUCH_SERVER }, - { "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR }, - { "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT }, - { "WERR_INVALID_COMPUTERNAME", WERR_INVALID_COMPUTERNAME }, - { "WERR_INVALID_DOMAINNAME", WERR_INVALID_DOMAINNAME }, - { "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED }, - { "WERR_DC_NOT_FOUND", WERR_DC_NOT_FOUND }, - { "WERR_SETUP_NOT_JOINED", WERR_SETUP_NOT_JOINED }, - { "WERR_SETUP_ALREADY_JOINED", WERR_SETUP_ALREADY_JOINED }, - { "WERR_SETUP_DOMAIN_CONTROLLER", WERR_SETUP_DOMAIN_CONTROLLER }, - { "WERR_DEFAULT_JOIN_REQUIRED", WERR_DEFAULT_JOIN_REQUIRED }, - { "WERR_DEVICE_NOT_AVAILABLE", WERR_DEVICE_NOT_AVAILABLE }, - { "WERR_LOGON_FAILURE", WERR_LOGON_FAILURE }, - { "WERR_WRONG_PASSWORD", WERR_WRONG_PASSWORD }, - { "WERR_PASSWORD_RESTRICTION", WERR_PASSWORD_RESTRICTION }, - { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN }, - { "WERR_NONE_MAPPED", WERR_NONE_MAPPED }, - { "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR }, - { "WERR_INVALID_DOMAIN_STATE", WERR_INVALID_DOMAIN_STATE }, - { "WERR_INVALID_DOMAIN_ROLE", WERR_INVALID_DOMAIN_ROLE }, - { "WERR_SPECIAL_ACCOUNT", WERR_SPECIAL_ACCOUNT }, - { "WERR_ALIAS_EXISTS", WERR_ALIAS_EXISTS }, - { "WERR_NO_SUCH_ALIAS", WERR_NO_SUCH_ALIAS }, - { "WERR_MEMBER_IN_ALIAS", WERR_MEMBER_IN_ALIAS }, - { "WERR_TIME_SKEW", WERR_TIME_SKEW }, - { "WERR_INVALID_OWNER", WERR_INVALID_OWNER }, - { "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE }, - { "WERR_IO_PENDING", WERR_IO_PENDING }, - { "WERR_INVALID_SERVICE_CONTROL", WERR_INVALID_SERVICE_CONTROL }, - { "WERR_SERVICE_ALREADY_RUNNING", WERR_SERVICE_ALREADY_RUNNING }, - { "WERR_NET_NAME_NOT_FOUND", WERR_NET_NAME_NOT_FOUND }, - { "WERR_REG_CORRUPT", WERR_REG_CORRUPT }, - { "WERR_REG_IO_FAILURE", WERR_REG_IO_FAILURE }, - { "WERR_REG_FILE_INVALID", WERR_REG_FILE_INVALID }, - { "WERR_NO_SUCH_SERVICE", WERR_NO_SUCH_SERVICE }, - { "WERR_SERVICE_DISABLED", WERR_SERVICE_DISABLED }, - { "WERR_SERVICE_NEVER_STARTED", WERR_SERVICE_NEVER_STARTED }, - { "WERR_NOT_FOUND", WERR_NOT_FOUND }, - { "WERR_CAN_NOT_COMPLETE", WERR_CAN_NOT_COMPLETE}, - { "WERR_INVALID_FLAGS", WERR_INVALID_FLAGS}, - { "WERR_PASSWORD_MUST_CHANGE", WERR_PASSWORD_MUST_CHANGE }, - { "WERR_DOMAIN_CONTROLLER_NOT_FOUND", WERR_DOMAIN_CONTROLLER_NOT_FOUND }, - { "WERR_ACCOUNT_LOCKED_OUT", WERR_ACCOUNT_LOCKED_OUT }, - { "WERR_DS_DRA_BAD_DN", WERR_DS_DRA_BAD_DN }, - { "WERR_DS_DRA_BAD_NC", WERR_DS_DRA_BAD_NC }, - { NULL, W_ERROR(0) } -}; - -werror_str_struct dos_err_strs[] = { - { WERR_OK, "Success" }, - { WERR_ACCESS_DENIED, "Access is denied" }, - { WERR_INVALID_PARAM, "Invalid parameter" }, - { WERR_NOT_SUPPORTED, "Not supported" }, - { WERR_BAD_PASSWORD, "A bad password was supplied" }, - { WERR_NOMEM, "Out of memory" }, - { WERR_NO_LOGON_SERVERS, "No logon servers found" }, - { WERR_NO_SUCH_LOGON_SESSION, "No such logon session" }, - { WERR_DOMAIN_CONTROLLER_NOT_FOUND, "A domain controller could not be found" }, - { WERR_DC_NOT_FOUND, "A domain controller could not be found" }, - { WERR_SETUP_NOT_JOINED, "Join failed" }, - { WERR_SETUP_ALREADY_JOINED, "Machine is already joined" }, - { WERR_SETUP_DOMAIN_CONTROLLER, "Machine is a Domain Controller" }, - { WERR_LOGON_FAILURE, "Invalid logon credentials" }, - { WERR_USER_EXISTS, "User account already exists" }, - { WERR_PASSWORD_MUST_CHANGE, "The password must be changed" }, - { WERR_ACCOUNT_LOCKED_OUT, "Account locked out" }, - { WERR_TIME_SKEW, "Time difference between client and server" }, - { WERR_USER_ALREADY_EXISTS, "User already exists" }, - { WERR_PASSWORD_RESTRICTION, "Password does not meet restrictions" }, - { WERR_NONE_MAPPED, "Could not map names to SIDs" }, - { WERR_NO_SUCH_USER, "No such User" }, - { WERR_GROUP_EXISTS, "Group already exists" }, - { WERR_DS_DRA_BAD_DN, "An invalid distinguished name was specified for this replication" }, - { WERR_DS_DRA_BAD_NC, "An invalid naming context was specified for this replication operation" }, - { WERR_WRONG_PASSWORD, "The current password is incorrect" } -}; - -/***************************************************************************** - Returns a DOS error message. not amazingly helpful, but better than a number. - *****************************************************************************/ - -const char *dos_errstr(WERROR werror) -{ - char *result; - int idx = 0; - - while (dos_errs[idx].dos_errstr != NULL) { - if (W_ERROR_V(dos_errs[idx].werror) == - W_ERROR_V(werror)) - return dos_errs[idx].dos_errstr; - idx++; - } - - result = talloc_asprintf(talloc_tos(), "DOS code 0x%08x", - W_ERROR_V(werror)); - SMB_ASSERT(result != NULL); - return result; -} - -/***************************************************************************** - Get friendly error string for WERRORs - *****************************************************************************/ - -const char *get_friendly_werror_msg(WERROR werror) -{ - int i = 0; - - for (i = 0; i < ARRAY_SIZE(dos_err_strs); i++) { - if (W_ERROR_V(dos_err_strs[i].werror) == - W_ERROR_V(werror)) { - return dos_err_strs[i].friendly_errstr; - } - } - - return dos_errstr(werror); -} - -/* compat function for samba4 */ -const char *win_errstr(WERROR werror) -{ - return dos_errstr(werror); -} diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index ff0a8f9808..d8c2b70175 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -1040,6 +1040,8 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, r->data.nt4 = logon1; r->ntver = nt_version; + map_netlogon_samlogon_response(r); + namecache_store(tmp_dc_name, NBT_NAME_SERVER, 1, &ip_list); goto make_reply; diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c index 1ba230cefe..465d88a9b6 100644 --- a/source3/libsmb/nterr.c +++ b/source3/libsmb/nterr.c @@ -532,6 +532,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS }, { "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT }, { "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE }, + { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY }, { "NT_STATUS_DS_NO_MORE_RIDS", NT_STATUS_DS_NO_MORE_RIDS }, { "NT_STATUS_NOT_A_REPARSE_POINT", NT_STATUS_NOT_A_REPARSE_POINT }, { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, diff --git a/source3/libsmb/ntlm_check.c b/source3/libsmb/ntlm_check.c index ae10d7373d..9380a83ea0 100644 --- a/source3/libsmb/ntlm_check.c +++ b/source3/libsmb/ntlm_check.c @@ -40,19 +40,19 @@ static bool smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); /* No password set - always false ! */ - return False; + return false; } if (sec_blob->length != 8) { DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect challenge size (%lu)\n", (unsigned long)sec_blob->length)); - return False; + return false; } if (nt_response->length != 24) { DEBUG(0, ("smb_pwd_check_ntlmv1: incorrect password length (%lu)\n", (unsigned long)nt_response->length)); - return False; + return false; } SMBOWFencrypt(part_passwd, sec_blob->data, p24); @@ -62,7 +62,7 @@ static bool smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, } -#ifdef DEBUG_PASSWORD +#if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |\n")); dump_data(100, part_passwd, 16); DEBUGADD(100,("Password from client was |\n")); @@ -80,30 +80,31 @@ static bool smb_pwd_check_ntlmv1(const DATA_BLOB *nt_response, Note: The same code works with both NTLMv2 and LMv2. ****************************************************************************/ -static bool smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, - const uchar *part_passwd, +static bool smb_pwd_check_ntlmv2(TALLOC_CTX *mem_ctx, + const DATA_BLOB *ntv2_response, + const uint8_t *part_passwd, const DATA_BLOB *sec_blob, const char *user, const char *domain, bool upper_case_domain, /* should the domain be transformed into upper case? */ DATA_BLOB *user_sess_key) { /* Finish the encryption of part_passwd. */ - uchar kr[16]; - uchar value_from_encryption[16]; - uchar client_response[16]; + uint8_t kr[16]; + uint8_t value_from_encryption[16]; + uint8_t client_response[16]; DATA_BLOB client_key_data; bool res; if (part_passwd == NULL) { DEBUG(10,("No password set - DISALLOWING access\n")); - /* No password set - always False */ - return False; + /* No password set - always false */ + return false; } if (sec_blob->length != 8) { DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect challenge size (%lu)\n", (unsigned long)sec_blob->length)); - return False; + return false; } if (ntv2_response->length < 24) { @@ -112,10 +113,10 @@ static bool smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, for LMv2, let alone NTLMv2. */ DEBUG(0, ("smb_pwd_check_ntlmv2: incorrect password length (%lu)\n", (unsigned long)ntv2_response->length)); - return False; + return false; } - client_key_data = data_blob(ntv2_response->data+16, ntv2_response->length-16); + client_key_data = data_blob_talloc(mem_ctx, ntv2_response->data+16, ntv2_response->length-16); /* todo: should we be checking this for anything? We can't for LMv2, but for NTLMv2 it is meant to contain the current time etc. @@ -124,7 +125,7 @@ static bool smb_pwd_check_ntlmv2(const DATA_BLOB *ntv2_response, memcpy(client_response, ntv2_response->data, sizeof(client_response)); if (!ntv2_owf_gen(part_passwd, user, domain, upper_case_domain, kr)) { - return False; + return false; } SMBOWFencrypt_ntv2(kr, sec_blob, &client_key_data, value_from_encryption); @@ -178,7 +179,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, const char *username, const char *client_username, const char *client_domain, - const uint8 *lm_pw, const uint8 *nt_pw, + const uint8_t *lm_pw, const uint8_t *nt_pw, DATA_BLOB *user_sess_key, DATA_BLOB *lm_sess_key) { @@ -288,7 +289,8 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, use it */ DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2( nt_response, + if (smb_pwd_check_ntlmv2(mem_ctx, + nt_response, nt_pw, challenge, client_username, client_domain, @@ -298,17 +300,19 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, } DEBUG(4,("ntlm_password_check: Checking NTLMv2 password with uppercased version of domain [%s]\n", client_domain)); - if (smb_pwd_check_ntlmv2( nt_response, + if (smb_pwd_check_ntlmv2(mem_ctx, + nt_response, nt_pw, challenge, client_username, client_domain, - True, + true, user_sess_key)) { return NT_STATUS_OK; } DEBUG(4,("ntlm_password_check: Checking NTLMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( nt_response, + if (smb_pwd_check_ntlmv2(mem_ctx, + nt_response, nt_pw, challenge, client_username, "", @@ -333,7 +337,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, so use it only if we otherwise allow LM authentication */ if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; + uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); if (lm_sess_key) { @@ -376,7 +380,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, if (smb_pwd_check_ntlmv1(lm_response, lm_pw, challenge, NULL)) { - uint8 first_8_lm_hash[16]; + uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); if (user_sess_key) { @@ -399,31 +403,34 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - related to Win9X, legacy NAS pass-though authentication */ DEBUG(4,("ntlm_password_check: Checking LMv2 password with domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2( lm_response, + if (smb_pwd_check_ntlmv2(mem_ctx, + lm_response, nt_pw, challenge, client_username, client_domain, - False, + false, NULL)) { return NT_STATUS_OK; } DEBUG(4,("ntlm_password_check: Checking LMv2 password with upper-cased version of domain %s\n", client_domain)); - if (smb_pwd_check_ntlmv2( lm_response, + if (smb_pwd_check_ntlmv2(mem_ctx, + lm_response, nt_pw, challenge, client_username, client_domain, - True, + true, NULL)) { return NT_STATUS_OK; } DEBUG(4,("ntlm_password_check: Checking LMv2 password without a domain\n")); - if (smb_pwd_check_ntlmv2( lm_response, + if (smb_pwd_check_ntlmv2(mem_ctx, + lm_response, nt_pw, challenge, client_username, "", - False, + false, NULL)) { return NT_STATUS_OK; } @@ -441,7 +448,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, allow LM authentication */ if (lp_lanman_auth() && lm_pw) { - uint8 first_8_lm_hash[16]; + uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, lm_pw, 8); memset(first_8_lm_hash + 8, '\0', 8); if (user_sess_key) { diff --git a/source3/modules/gpfs.c b/source3/modules/gpfs.c index 590dbac26f..a0d33fa33a 100644 --- a/source3/modules/gpfs.c +++ b/source3/modules/gpfs.c @@ -141,40 +141,40 @@ void init_gpfs(void) return; } - libgpfs_handle = sys_dlopen("libgpfs_gpl.so", RTLD_LAZY); + libgpfs_handle = dlopen("libgpfs_gpl.so", RTLD_LAZY); if (libgpfs_handle == NULL) { - DEBUG(10, ("sys_dlopen for libgpfs_gpl failed: %s\n", + DEBUG(10, ("dlopen for libgpfs_gpl failed: %s\n", strerror(errno))); return; } DEBUG(10, ("libgpfs_gpl.so loaded\n")); - gpfs_set_share_fn = sys_dlsym(libgpfs_handle, "gpfs_set_share"); + gpfs_set_share_fn = dlsym(libgpfs_handle, "gpfs_set_share"); if (gpfs_set_share_fn == NULL) { DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " "'gpfs_set_share'\n")); goto failed; } - gpfs_set_lease_fn = sys_dlsym(libgpfs_handle, "gpfs_set_lease"); + gpfs_set_lease_fn = dlsym(libgpfs_handle, "gpfs_set_lease"); if (gpfs_set_lease_fn == NULL) { DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " "'gpfs_set_lease'\n")); - sys_dlclose(libgpfs_handle); + dlclose(libgpfs_handle); goto failed; } - gpfs_getacl_fn = sys_dlsym(libgpfs_handle, "gpfs_getacl"); + gpfs_getacl_fn = dlsym(libgpfs_handle, "gpfs_getacl"); if (gpfs_getacl_fn == NULL) { DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " "'gpfs_getacl'\n")); goto failed; } - gpfs_putacl_fn = sys_dlsym(libgpfs_handle, "gpfs_putacl"); + gpfs_putacl_fn = dlsym(libgpfs_handle, "gpfs_putacl"); if (gpfs_putacl_fn == NULL) { DEBUG(3, ("libgpfs_gpl.so does not contain the symbol " "'gpfs_putacl'\n")); @@ -187,7 +187,7 @@ void init_gpfs(void) return; failed: - sys_dlclose(libgpfs_handle); + dlclose(libgpfs_handle); /* leave libgpfs_handle != NULL around, no point in trying twice */ gpfs_set_share_fn = NULL; diff --git a/source3/modules/vfs_acl_tdb.c b/source3/modules/vfs_acl_tdb.c new file mode 100644 index 0000000000..202c1a8469 --- /dev/null +++ b/source3/modules/vfs_acl_tdb.c @@ -0,0 +1,843 @@ +/* + * Store Windows ACLs in xattrs, or a tdb if configured that way. + * + * Copyright (C) Volker Lendecke, 2008 + * Copyright (C) Jeremy Allison, 2008 + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +/* NOTE: This is an experimental module, not yet finished. JRA. */ + +#include "includes.h" +#include "librpc/gen_ndr/xattr.h" +#include "librpc/gen_ndr/ndr_xattr.h" + +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +static unsigned int ref_count; +static struct db_context *acl_db; + +/******************************************************************* + Open acl_db if not already open, increment ref count. +*******************************************************************/ + +static bool acl_tdb_init(struct db_context **pp_db) +{ + const char *dbname; + + if (acl_db) { + *pp_db = acl_db; + ref_count++; + return true; + } + + dbname = lock_path("file_ntacls.tdb"); + + if (dbname == NULL) { + errno = ENOSYS; + return false; + } + + become_root(); + *pp_db = db_open(NULL, dbname, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600); + unbecome_root(); + + if (*pp_db == NULL) { +#if defined(ENOTSUP) + errno = ENOTSUP; +#else + errno = ENOSYS; +#endif + return false; + } + + ref_count++; + return true; +} + +/******************************************************************* + Lower ref count and close acl_db if zero. +*******************************************************************/ + +static void free_acl_xattr_data(void **pptr) +{ + struct db_context **pp_db = (struct db_context **)pptr; + + ref_count--; + if (ref_count == 0) { + TALLOC_FREE(*pp_db); + acl_db = NULL; + } +} + +/******************************************************************* + Fetch_lock the tdb acl record for a file +*******************************************************************/ + +static struct db_record *acl_xattr_tdb_lock(TALLOC_CTX *mem_ctx, + struct db_context *db, + const struct file_id *id) +{ + uint8 id_buf[16]; + push_file_id_16((char *)id_buf, id); + return db->fetch_locked(db, + mem_ctx, + make_tdb_data(id_buf, + sizeof(id_buf))); +} + +/******************************************************************* + Parse out a struct security_descriptor from a DATA_BLOB. +*******************************************************************/ + +static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, + uint32 security_info, + struct security_descriptor **ppdesc) +{ + TALLOC_CTX *ctx = talloc_tos(); + struct xattr_NTACL xacl; + enum ndr_err_code ndr_err; + size_t sd_size; + + ndr_err = ndr_pull_struct_blob(pblob, ctx, NULL, &xacl, + (ndr_pull_flags_fn_t)ndr_pull_xattr_NTACL); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(5, ("parse_acl_blob: ndr_pull_xattr_NTACL failed: %s\n", + ndr_errstr(ndr_err))); + return ndr_map_error2ntstatus(ndr_err);; + } + + if (xacl.version != 2) { + return NT_STATUS_REVISION_MISMATCH; + } + + *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_ts->sd->type | SEC_DESC_SELF_RELATIVE, + (security_info & OWNER_SECURITY_INFORMATION) + ? xacl.info.sd_ts->sd->owner_sid : NULL, + (security_info & GROUP_SECURITY_INFORMATION) + ? xacl.info.sd_ts->sd->group_sid : NULL, + (security_info & SACL_SECURITY_INFORMATION) + ? xacl.info.sd_ts->sd->sacl : NULL, + (security_info & DACL_SECURITY_INFORMATION) + ? xacl.info.sd_ts->sd->dacl : NULL, + &sd_size); + + TALLOC_FREE(xacl.info.sd); + + return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; +} + +/******************************************************************* + Pull a security descriptor into a DATA_BLOB from a tdb store. +*******************************************************************/ + +static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, + vfs_handle_struct *handle, + files_struct *fsp, + const char *name, + DATA_BLOB *pblob) +{ + uint8 id_buf[16]; + TDB_DATA data; + struct file_id id; + struct db_context *db; + SMB_STRUCT_STAT sbuf; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, + return NT_STATUS_INTERNAL_DB_CORRUPTION); + + if (fsp && fsp->fh->fd != -1) { + if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + return map_nt_error_from_unix(errno); + } + } else { + if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) { + return map_nt_error_from_unix(errno); + } + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + + push_file_id_16((char *)id_buf, &id); + + if (db->fetch(db, + ctx, + make_tdb_data(id_buf, sizeof(id_buf)), + &data) == -1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + + pblob->data = data.dptr; + pblob->length = data.dsize; + + DEBUG(10,("get_acl_blob: returned %u bytes from file %s\n", + (unsigned int)data.dsize, name )); + + if (pblob->length == 0 || pblob->data == NULL) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } + return NT_STATUS_OK; +} + +/******************************************************************* + Create a DATA_BLOB from a security descriptor. +*******************************************************************/ + +static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob) +{ + struct xattr_NTACL xacl; + struct security_descriptor_timestamp sd_ts; + enum ndr_err_code ndr_err; + TALLOC_CTX *ctx = talloc_tos(); + struct timespec curr = timespec_current(); + + ZERO_STRUCT(xacl); + ZERO_STRUCT(sd_ts); + + /* Horrid hack as setting an xattr changes the ctime + * on Linux. This gives a race of 1 second during + * which we would not see a POSIX ACL set. + */ + curr.tv_sec += 1; + + xacl.version = 2; + xacl.info.sd_ts = &sd_ts; + xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd); + unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr); + + DEBUG(10, ("create_acl_blob: timestamp stored as %s\n", + timestring(ctx, curr.tv_sec) )); + + ndr_err = ndr_push_struct_blob( + pblob, ctx, NULL, &xacl, + (ndr_push_flags_fn_t)ndr_push_xattr_NTACL); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(5, ("create_acl_blob: ndr_push_xattr_NTACL failed: %s\n", + ndr_errstr(ndr_err))); + return ndr_map_error2ntstatus(ndr_err);; + } + + return NT_STATUS_OK; +} + +/******************************************************************* + Store a DATA_BLOB into a tdb record given an fsp pointer. +*******************************************************************/ + +static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, + files_struct *fsp, + DATA_BLOB *pblob) +{ + uint8 id_buf[16]; + struct file_id id; + SMB_STRUCT_STAT sbuf; + TDB_DATA data; + struct db_context *db; + struct db_record *rec; + + DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", + (unsigned int)pblob->length, fsp->fsp_name)); + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, + return NT_STATUS_INTERNAL_DB_CORRUPTION); + + if (fsp->fh->fd != -1) { + if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { + return map_nt_error_from_unix(errno); + } + } else { + if (SMB_VFS_STAT(handle->conn, fsp->fsp_name, &sbuf) == -1) { + return map_nt_error_from_unix(errno); + } + } + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + + push_file_id_16((char *)id_buf, &id); + rec = db->fetch_locked(db, talloc_tos(), + make_tdb_data(id_buf, + sizeof(id_buf))); + if (rec == NULL) { + DEBUG(0, ("store_acl_blob_fsp_tdb: fetch_lock failed\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + data.dptr = pblob->data; + data.dsize = pblob->length; + return rec->store(rec, data, 0); +} + +/******************************************************************* + Store a DATA_BLOB into a tdb record given a pathname. +*******************************************************************/ + +static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, + const char *fname, + DATA_BLOB *pblob) +{ + uint8 id_buf[16]; + struct file_id id; + TDB_DATA data; + SMB_STRUCT_STAT sbuf; + struct db_context *db; + struct db_record *rec; + + DEBUG(10,("store_acl_blob_pathname: storing blob " + "length %u on file %s\n", + (unsigned int)pblob->length, fname)); + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, + return NT_STATUS_INTERNAL_DB_CORRUPTION); + + if (SMB_VFS_STAT(handle->conn, fname, &sbuf) == -1) { + return map_nt_error_from_unix(errno); + } + + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + push_file_id_16((char *)id_buf, &id); + + rec = db->fetch_locked(db, talloc_tos(), + make_tdb_data(id_buf, + sizeof(id_buf))); + if (rec == NULL) { + DEBUG(0, ("store_acl_blob_pathname_tdb: fetch_lock failed\n")); + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } + data.dptr = pblob->data; + data.dsize = pblob->length; + return rec->store(rec, data, 0); +} + +/******************************************************************* + Store a DATA_BLOB into an xattr given a pathname. +*******************************************************************/ + +static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, + files_struct *fsp, + const char *name, + uint32 security_info, + struct security_descriptor **ppdesc) +{ + TALLOC_CTX *ctx = talloc_tos(); + DATA_BLOB blob; + NTSTATUS status; + + if (fsp && name == NULL) { + name = fsp->fsp_name; + } + + DEBUG(10, ("get_nt_acl_xattr_internal: name=%s\n", name)); + + status = get_acl_blob(ctx, handle, fsp, name, &blob); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("get_acl_blob returned %s\n", nt_errstr(status))); + return status; + } + + status = parse_acl_blob(&blob, security_info, ppdesc); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("parse_acl_blob returned %s\n", + nt_errstr(status))); + return status; + } + + TALLOC_FREE(blob.data); + return status; +} + +/********************************************************************* + Create a default security descriptor for a file in case no inheritance + exists. All permissions to the owner and SYSTEM. +*********************************************************************/ + +static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, + SMB_STRUCT_STAT *psbuf) +{ + struct dom_sid owner_sid, group_sid; + size_t sd_size; + struct security_ace *pace = NULL; + struct security_acl *pacl = NULL; + + uid_to_sid(&owner_sid, psbuf->st_uid); + gid_to_sid(&group_sid, psbuf->st_gid); + + pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2); + if (!pace) { + return NULL; + } + + init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_ALL, 0); + init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_ALL, 0); + + pacl = make_sec_acl(mem_ctx, + NT4_ACL_REVISION, + 2, + pace); + if (!pacl) { + return NULL; + } + return make_sec_desc(mem_ctx, + SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT, + &owner_sid, + &group_sid, + NULL, + pacl, + &sd_size); +} + +/********************************************************************* +*********************************************************************/ + +static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, + const char *fname, + files_struct *fsp, + bool container) +{ + TALLOC_CTX *ctx = talloc_tos(); + NTSTATUS status; + struct security_descriptor *parent_desc = NULL; + struct security_descriptor *psd = NULL; + DATA_BLOB blob; + size_t size; + char *parent_name; + + if (!parent_dirname_talloc(ctx, + fname, + &parent_name, + NULL)) { + return NT_STATUS_NO_MEMORY; + } + + DEBUG(10,("inherit_new_acl: check directory %s\n", + parent_name)); + + status = get_nt_acl_xattr_internal(handle, + NULL, + parent_name, + (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION), + &parent_desc); + if (NT_STATUS_IS_OK(status)) { + /* Create an inherited descriptor from the parent. */ + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("inherit_new_acl: parent acl is:\n")); + NDR_PRINT_DEBUG(security_descriptor, parent_desc); + } + + status = se_create_child_secdesc(ctx, + &psd, + &size, + parent_desc, + &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX], + &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX], + container); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("inherit_new_acl: child acl is:\n")); + NDR_PRINT_DEBUG(security_descriptor, psd); + } + + } else { + DEBUG(10,("inherit_new_acl: directory %s failed " + "to get acl %s\n", + parent_name, + nt_errstr(status) )); + } + + if (!psd || psd->dacl == NULL) { + SMB_STRUCT_STAT sbuf; + int ret; + + TALLOC_FREE(psd); + if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { + ret = SMB_VFS_FSTAT(fsp, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + psd = default_file_sd(ctx, &sbuf); + if (!psd) { + return NT_STATUS_NO_MEMORY; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("inherit_new_acl: default acl is:\n")); + NDR_PRINT_DEBUG(security_descriptor, psd); + } + } + + status = create_acl_blob(psd, &blob); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + if (fsp) { + return store_acl_blob_fsp(handle, fsp, &blob); + } else { + return store_acl_blob_pathname(handle, fname, &blob); + } +} + +/********************************************************************* + Check ACL on open. For new files inherit from parent directory. +*********************************************************************/ + +static int open_acl_xattr(vfs_handle_struct *handle, + const char *fname, + files_struct *fsp, + int flags, + mode_t mode) +{ + uint32_t access_granted = 0; + struct security_descriptor *pdesc = NULL; + bool file_existed = true; + NTSTATUS status = get_nt_acl_xattr_internal(handle, + NULL, + fname, + (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION), + &pdesc); + if (NT_STATUS_IS_OK(status)) { + /* See if we can access it. */ + status = smb1_file_se_access_check(pdesc, + handle->conn->server_info->ptok, + fsp->access_mask, + &access_granted); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("open_acl_xattr: file %s open " + "refused with error %s\n", + fname, + nt_errstr(status) )); + errno = map_errno_from_nt_status(status); + return -1; + } + } else if (NT_STATUS_EQUAL(status,NT_STATUS_OBJECT_NAME_NOT_FOUND)) { + file_existed = false; + } + + DEBUG(10,("open_acl_xattr: get_nt_acl_attr_internal for " + "file %s returned %s\n", + fname, + nt_errstr(status) )); + + fsp->fh->fd = SMB_VFS_NEXT_OPEN(handle, fname, fsp, flags, mode); + + if (!file_existed && fsp->fh->fd != -1) { + /* File was created. Inherit from parent directory. */ + string_set(&fsp->fsp_name, fname); + inherit_new_acl(handle, fname, fsp, false); + } + + return fsp->fh->fd; +} + +/********************************************************************* + On unlink we need to delete the tdb record (if using tdb). +*********************************************************************/ + +static int unlink_acl_xattr(vfs_handle_struct *handle, const char *path) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + struct db_record *rec; + int ret; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + ret = SMB_VFS_NEXT_UNLINK(handle, path); + + if (ret == -1) { + return -1; + } + + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + + rec = acl_xattr_tdb_lock(talloc_tos(), db, &id); + + /* + * If rec == NULL there's not much we can do about it + */ + + if (rec == NULL) { + DEBUG(10,("unlink_acl_xattr: path %s rec == NULL\n", + path )); + TALLOC_FREE(rec); + return 0; + } + + rec->delete_rec(rec); + TALLOC_FREE(rec); + + return 0; +} + +/********************************************************************* + Store an inherited SD on mkdir. +*********************************************************************/ + +static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + int ret = SMB_VFS_NEXT_MKDIR(handle, path, mode); + + if (ret == -1) { + return ret; + } + /* New directory - inherit from parent. */ + inherit_new_acl(handle, path, NULL, true); + return ret; +} + +/********************************************************************* + On rmdir we need to delete the tdb record (if using tdb). +*********************************************************************/ + +static int rmdir_acl_xattr(vfs_handle_struct *handle, const char *path) +{ + SMB_STRUCT_STAT sbuf; + struct file_id id; + struct db_context *db; + struct db_record *rec; + int ret; + + SMB_VFS_HANDLE_GET_DATA(handle, db, struct db_context, return -1); + + if (SMB_VFS_STAT(handle->conn, path, &sbuf) == -1) { + return -1; + } + + ret = SMB_VFS_NEXT_RMDIR(handle, path); + + if (ret == -1) { + return -1; + } + + id = vfs_file_id_from_sbuf(handle->conn, &sbuf); + + rec = acl_xattr_tdb_lock(talloc_tos(), db, &id); + + /* + * If rec == NULL there's not much we can do about it + */ + + if (rec == NULL) { + DEBUG(10,("rmdir_acl_xattr: path %s rec == NULL\n", + path )); + TALLOC_FREE(rec); + return 0; + } + + rec->delete_rec(rec); + TALLOC_FREE(rec); + + return 0; +} + +/********************************************************************* + Fetch a security descriptor given an fsp. +*********************************************************************/ + +static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, + uint32 security_info, struct security_descriptor **ppdesc) +{ + NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp, + NULL, security_info, ppdesc); + if (NT_STATUS_IS_OK(status)) { + if (DEBUGLEVEL >= 10) { + DEBUG(10,("fget_nt_acl_xattr: returning xattr sd for file %s\n", + fsp->fsp_name)); + NDR_PRINT_DEBUG(security_descriptor, *ppdesc); + } + return NT_STATUS_OK; + } + + DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", + fsp->fsp_name, + nt_errstr(status) )); + + return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, + security_info, ppdesc); +} + +/********************************************************************* + Fetch a security descriptor given a pathname. +*********************************************************************/ + +static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, + const char *name, uint32 security_info, struct security_descriptor **ppdesc) +{ + NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, + name, security_info, ppdesc); + if (NT_STATUS_IS_OK(status)) { + if (DEBUGLEVEL >= 10) { + DEBUG(10,("get_nt_acl_xattr: returning xattr sd for file %s\n", + name)); + NDR_PRINT_DEBUG(security_descriptor, *ppdesc); + } + return NT_STATUS_OK; + } + + DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", + name, + nt_errstr(status) )); + + return SMB_VFS_NEXT_GET_NT_ACL(handle, name, + security_info, ppdesc); +} + +/********************************************************************* + Store a security descriptor given an fsp. +*********************************************************************/ + +static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, + uint32 security_info_sent, const struct security_descriptor *psd) +{ + NTSTATUS status; + DATA_BLOB blob; + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", + fsp->fsp_name)); + NDR_PRINT_DEBUG(security_descriptor, + CONST_DISCARD(struct security_descriptor *,psd)); + } + + status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + /* Ensure owner and group are set. */ + if (!psd->owner_sid || !psd->group_sid) { + int ret; + SMB_STRUCT_STAT sbuf; + DOM_SID owner_sid, group_sid; + struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd); + + if (!nc_psd) { + return NT_STATUS_OK; + } + if (fsp->is_directory || fsp->fh->fd == -1) { + ret = SMB_VFS_STAT(fsp->conn,fsp->fsp_name, &sbuf); + } else { + ret = SMB_VFS_FSTAT(fsp, &sbuf); + } + if (ret == -1) { + /* Lower level acl set succeeded, + * so still return OK. */ + return NT_STATUS_OK; + } + create_file_sids(&sbuf, &owner_sid, &group_sid); + /* This is safe as nc_psd is discarded at fn exit. */ + nc_psd->owner_sid = &owner_sid; + nc_psd->group_sid = &group_sid; + security_info_sent |= (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION); + psd = nc_psd; + } + + if ((security_info_sent & DACL_SECURITY_INFORMATION) && + psd->dacl != NULL && + (psd->type & (SE_DESC_DACL_AUTO_INHERITED| + SE_DESC_DACL_AUTO_INHERIT_REQ))== + (SE_DESC_DACL_AUTO_INHERITED| + SE_DESC_DACL_AUTO_INHERIT_REQ) ) { + struct security_descriptor *new_psd = NULL; + status = append_parent_acl(fsp, psd, &new_psd); + if (!NT_STATUS_IS_OK(status)) { + /* Lower level acl set succeeded, + * so still return OK. */ + return NT_STATUS_OK; + } + psd = new_psd; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n", + fsp->fsp_name)); + NDR_PRINT_DEBUG(security_descriptor, + CONST_DISCARD(struct security_descriptor *,psd)); + } + create_acl_blob(psd, &blob); + store_acl_blob_fsp(handle, fsp, &blob); + + return NT_STATUS_OK; +} + +/******************************************************************* + Handle opening the storage tdb if so configured. +*******************************************************************/ + +static int connect_acl_xattr(struct vfs_handle_struct *handle, + const char *service, + const char *user) +{ + struct db_context *db; + int res; + + res = SMB_VFS_NEXT_CONNECT(handle, service, user); + if (res < 0) { + return res; + } + + if (!acl_tdb_init(&db)) { + SMB_VFS_NEXT_DISCONNECT(handle); + return -1; + } + + SMB_VFS_HANDLE_SET_DATA(handle, db, free_acl_xattr_data, + struct db_context, return -1); + + return 0; +} + +/* VFS operations structure */ + +static vfs_op_tuple skel_op_tuples[] = +{ + {SMB_VFS_OP(connect_acl_xattr), SMB_VFS_OP_CONNECT, SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(mkdir_acl_xattr), SMB_VFS_OP_MKDIR, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(rmdir_acl_xattr), SMB_VFS_OP_RMDIR, SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(open_acl_xattr), SMB_VFS_OP_OPEN, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(unlink_acl_xattr), SMB_VFS_OP_UNLINK, SMB_VFS_LAYER_TRANSPARENT}, + + /* NT File ACL operations */ + + {SMB_VFS_OP(fget_nt_acl_xattr),SMB_VFS_OP_FGET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(get_nt_acl_xattr), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(fset_nt_acl_xattr),SMB_VFS_OP_FSET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_acl_xattr_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "acl_tdb", skel_op_tuples); +} diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index ca34e97155..2b4e68bdea 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -27,8 +27,11 @@ #undef DBGC_CLASS #define DBGC_CLASS DBGC_VFS +/******************************************************************* + Parse out a struct security_descriptor from a DATA_BLOB. +*******************************************************************/ + static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, - const struct timespec cts, uint32 security_info, struct security_descriptor **ppdesc) { @@ -50,31 +53,7 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, return NT_STATUS_REVISION_MISMATCH; } -#if 0 - { - struct timespec ts; - /* Arg. This doesn't work. Too many activities - * change the ctime. May have to roll back to - * version 1. - */ - /* - * Check that the ctime timestamp is ealier - * than the stored timestamp. - */ - - ts = nt_time_to_unix_timespec(&xacl.info.sd_ts->last_changed); - - if (timespec_compare(&cts, &ts) > 0) { - DEBUG(5, ("parse_acl_blob: stored ACL out of date " - "(%s > %s.\n", - timestring(ctx, cts.tv_sec), - timestring(ctx, ts.tv_sec))); - return NT_STATUS_EA_CORRUPT_ERROR; - } - } -#endif - - *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, SEC_DESC_SELF_RELATIVE, + *ppdesc = make_sec_desc(ctx, SEC_DESC_REVISION, xacl.info.sd_ts->sd->type | SEC_DESC_SELF_RELATIVE, (security_info & OWNER_SECURITY_INFORMATION) ? xacl.info.sd_ts->sd->owner_sid : NULL, (security_info & GROUP_SECURITY_INFORMATION) @@ -90,6 +69,10 @@ static NTSTATUS parse_acl_blob(const DATA_BLOB *pblob, return (*ppdesc != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY; } +/******************************************************************* + Pull a security descriptor into a DATA_BLOB from a xattr. +*******************************************************************/ + static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, vfs_handle_struct *handle, files_struct *fsp, @@ -144,7 +127,11 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, return NT_STATUS_OK; } -static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob) +/******************************************************************* + Create a DATA_BLOB from a security descriptor. +*******************************************************************/ + +static NTSTATUS create_acl_blob(const struct security_descriptor *psd, DATA_BLOB *pblob) { struct xattr_NTACL xacl; struct security_descriptor_timestamp sd_ts; @@ -163,7 +150,7 @@ static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob) xacl.version = 2; xacl.info.sd_ts = &sd_ts; - xacl.info.sd_ts->sd = CONST_DISCARD(SEC_DESC *, psd); + xacl.info.sd_ts->sd = CONST_DISCARD(struct security_descriptor *, psd); unix_timespec_to_nt_time(&xacl.info.sd_ts->last_changed, curr); DEBUG(10, ("create_acl_blob: timestamp stored as %s\n", @@ -182,7 +169,12 @@ static NTSTATUS create_acl_blob(const SEC_DESC *psd, DATA_BLOB *pblob) return NT_STATUS_OK; } -static NTSTATUS store_acl_blob_fsp(files_struct *fsp, +/******************************************************************* + Store a DATA_BLOB into an xattr given an fsp pointer. +*******************************************************************/ + +static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, + files_struct *fsp, DATA_BLOB *pblob) { int ret; @@ -215,10 +207,15 @@ static NTSTATUS store_acl_blob_fsp(files_struct *fsp, return NT_STATUS_OK; } -static NTSTATUS store_acl_blob_pathname(connection_struct *conn, +/******************************************************************* + Store a DATA_BLOB into an xattr given a pathname. +*******************************************************************/ + +static NTSTATUS store_acl_blob_pathname(vfs_handle_struct *handle, const char *fname, DATA_BLOB *pblob) { + connection_struct *conn = handle->conn; int ret; int saved_errno = 0; @@ -245,16 +242,18 @@ static NTSTATUS store_acl_blob_pathname(connection_struct *conn, return NT_STATUS_OK; } +/******************************************************************* + Store a DATA_BLOB into an xattr given a pathname. +*******************************************************************/ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, - SEC_DESC **ppdesc) + struct security_descriptor **ppdesc) { TALLOC_CTX *ctx = talloc_tos(); DATA_BLOB blob; - SMB_STRUCT_STAT sbuf; NTSTATUS status; if (fsp && name == NULL) { @@ -269,18 +268,7 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, return status; } - if (fsp && fsp->fh->fd != -1) { - if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } - } else { - if (SMB_VFS_STAT(handle->conn, name, &sbuf) == -1) { - return map_nt_error_from_unix(errno); - } - } - - status = parse_acl_blob(&blob, get_ctimespec(&sbuf), - security_info, ppdesc); + status = parse_acl_blob(&blob, security_info, ppdesc); if (!NT_STATUS_IS_OK(status)) { DEBUG(10, ("parse_acl_blob returned %s\n", nt_errstr(status))); @@ -292,8 +280,49 @@ static NTSTATUS get_nt_acl_xattr_internal(vfs_handle_struct *handle, } /********************************************************************* - * Currently this only works for existing files. Need to work on - * inheritance for new files. + Create a default security descriptor for a file in case no inheritance + exists. All permissions to the owner and SYSTEM. +*********************************************************************/ + +static struct security_descriptor *default_file_sd(TALLOC_CTX *mem_ctx, + SMB_STRUCT_STAT *psbuf) +{ + struct dom_sid owner_sid, group_sid; + size_t sd_size; + struct security_ace *pace = NULL; + struct security_acl *pacl = NULL; + + uid_to_sid(&owner_sid, psbuf->st_uid); + gid_to_sid(&group_sid, psbuf->st_gid); + + pace = TALLOC_ARRAY(mem_ctx, struct security_ace, 2); + if (!pace) { + return NULL; + } + + init_sec_ace(&pace[0], &owner_sid, SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_ALL, 0); + init_sec_ace(&pace[1], &global_sid_System, SEC_ACE_TYPE_ACCESS_ALLOWED, + SEC_RIGHTS_FILE_ALL, 0); + + pacl = make_sec_acl(mem_ctx, + NT4_ACL_REVISION, + 2, + pace); + if (!pacl) { + return NULL; + } + return make_sec_desc(mem_ctx, + SECURITY_DESCRIPTOR_REVISION_1, + SEC_DESC_SELF_RELATIVE|SEC_DESC_DACL_PRESENT, + &owner_sid, + &group_sid, + NULL, + pacl, + &sd_size); +} + +/********************************************************************* *********************************************************************/ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, @@ -303,8 +332,8 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, { TALLOC_CTX *ctx = talloc_tos(); NTSTATUS status; - SEC_DESC *parent_desc = NULL; - SEC_DESC *psd = NULL; + struct security_descriptor *parent_desc = NULL; + struct security_descriptor *psd = NULL; DATA_BLOB blob; size_t size; char *parent_name; @@ -322,35 +351,73 @@ static NTSTATUS inherit_new_acl(vfs_handle_struct *handle, status = get_nt_acl_xattr_internal(handle, NULL, parent_name, - DACL_SECURITY_INFORMATION, + (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION), &parent_desc); - if (!NT_STATUS_IS_OK(status)) { - DEBUG(10,("inherit_new_acl: directory %s failed " - "to get acl %s\n", - parent_name, - nt_errstr(status) )); - return status; - } + if (NT_STATUS_IS_OK(status)) { + /* Create an inherited descriptor from the parent. */ + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("inherit_new_acl: parent acl is:\n")); + NDR_PRINT_DEBUG(security_descriptor, parent_desc); + } - /* Create an inherited descriptor from the parent. */ - status = se_create_child_secdesc(ctx, + status = se_create_child_secdesc(ctx, &psd, &size, parent_desc, &handle->conn->server_info->ptok->user_sids[PRIMARY_USER_SID_INDEX], &handle->conn->server_info->ptok->user_sids[PRIMARY_GROUP_SID_INDEX], container); - if (!NT_STATUS_IS_OK(status)) { - return status; + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("inherit_new_acl: child acl is:\n")); + NDR_PRINT_DEBUG(security_descriptor, psd); + } + + } else { + DEBUG(10,("inherit_new_acl: directory %s failed " + "to get acl %s\n", + parent_name, + nt_errstr(status) )); + } + + if (!psd || psd->dacl == NULL) { + SMB_STRUCT_STAT sbuf; + int ret; + + TALLOC_FREE(psd); + if (fsp && !fsp->is_directory && fsp->fh->fd != -1) { + ret = SMB_VFS_FSTAT(fsp, &sbuf); + } else { + ret = SMB_VFS_STAT(handle->conn,fname, &sbuf); + } + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + psd = default_file_sd(ctx, &sbuf); + if (!psd) { + return NT_STATUS_NO_MEMORY; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10,("inherit_new_acl: default acl is:\n")); + NDR_PRINT_DEBUG(security_descriptor, psd); + } } + status = create_acl_blob(psd, &blob); if (!NT_STATUS_IS_OK(status)) { return status; } if (fsp) { - return store_acl_blob_fsp(fsp, &blob); + return store_acl_blob_fsp(handle, fsp, &blob); } else { - return store_acl_blob_pathname(handle->conn, fname, &blob); + return store_acl_blob_pathname(handle, fname, &blob); } } @@ -365,7 +432,7 @@ static int open_acl_xattr(vfs_handle_struct *handle, mode_t mode) { uint32_t access_granted = 0; - SEC_DESC *pdesc = NULL; + struct security_descriptor *pdesc = NULL; bool file_existed = true; NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, @@ -376,11 +443,15 @@ static int open_acl_xattr(vfs_handle_struct *handle, &pdesc); if (NT_STATUS_IS_OK(status)) { /* See if we can access it. */ - status = se_access_check(pdesc, + status = smb1_file_se_access_check(pdesc, handle->conn->server_info->ptok, fsp->access_mask, &access_granted); if (!NT_STATUS_IS_OK(status)) { + DEBUG(10,("open_acl_xattr: file %s open " + "refused with error %s\n", + fname, + nt_errstr(status) )); errno = map_errno_from_nt_status(status); return -1; } @@ -416,8 +487,12 @@ static int mkdir_acl_xattr(vfs_handle_struct *handle, const char *path, mode_t m return ret; } +/********************************************************************* + Fetch a security descriptor given an fsp. +*********************************************************************/ + static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info, SEC_DESC **ppdesc) + uint32 security_info, struct security_descriptor **ppdesc) { NTSTATUS status = get_nt_acl_xattr_internal(handle, fsp, NULL, security_info, ppdesc); @@ -429,12 +504,21 @@ static NTSTATUS fget_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, } return NT_STATUS_OK; } + + DEBUG(10,("fget_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", + fsp->fsp_name, + nt_errstr(status) )); + return SMB_VFS_NEXT_FGET_NT_ACL(handle, fsp, security_info, ppdesc); } +/********************************************************************* + Fetch a security descriptor given a pathname. +*********************************************************************/ + static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, - const char *name, uint32 security_info, SEC_DESC **ppdesc) + const char *name, uint32 security_info, struct security_descriptor **ppdesc) { NTSTATUS status = get_nt_acl_xattr_internal(handle, NULL, name, security_info, ppdesc); @@ -446,12 +530,21 @@ static NTSTATUS get_nt_acl_xattr(vfs_handle_struct *handle, } return NT_STATUS_OK; } + + DEBUG(10,("get_nt_acl_xattr: failed to get xattr sd for file %s, Error %s\n", + name, + nt_errstr(status) )); + return SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info, ppdesc); } +/********************************************************************* + Store a security descriptor given an fsp. +*********************************************************************/ + static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, - uint32 security_info_sent, const SEC_DESC *psd) + uint32 security_info_sent, const struct security_descriptor *psd) { NTSTATUS status; DATA_BLOB blob; @@ -460,7 +553,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", fsp->fsp_name)); NDR_PRINT_DEBUG(security_descriptor, - CONST_DISCARD(SEC_DESC *,psd)); + CONST_DISCARD(struct security_descriptor *,psd)); } status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); @@ -473,7 +566,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, int ret; SMB_STRUCT_STAT sbuf; DOM_SID owner_sid, group_sid; - SEC_DESC *nc_psd = dup_sec_desc(talloc_tos(), psd); + struct security_descriptor *nc_psd = dup_sec_desc(talloc_tos(), psd); if (!nc_psd) { return NT_STATUS_OK; @@ -502,7 +595,7 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, SE_DESC_DACL_AUTO_INHERIT_REQ))== (SE_DESC_DACL_AUTO_INHERITED| SE_DESC_DACL_AUTO_INHERIT_REQ) ) { - SEC_DESC *new_psd = NULL; + struct security_descriptor *new_psd = NULL; status = append_parent_acl(fsp, psd, &new_psd); if (!NT_STATUS_IS_OK(status)) { /* Lower level acl set succeeded, @@ -516,10 +609,10 @@ static NTSTATUS fset_nt_acl_xattr(vfs_handle_struct *handle, files_struct *fsp, DEBUG(10,("fset_nt_acl_xattr: storing xattr sd for file %s\n", fsp->fsp_name)); NDR_PRINT_DEBUG(security_descriptor, - CONST_DISCARD(SEC_DESC *,psd)); + CONST_DISCARD(struct security_descriptor *,psd)); } create_acl_blob(psd, &blob); - store_acl_blob_fsp(fsp, &blob); + store_acl_blob_fsp(handle, fsp, &blob); return NT_STATUS_OK; } @@ -537,7 +630,7 @@ static vfs_op_tuple skel_op_tuples[] = {SMB_VFS_OP(get_nt_acl_xattr), SMB_VFS_OP_GET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, {SMB_VFS_OP(fset_nt_acl_xattr),SMB_VFS_OP_FSET_NT_ACL,SMB_VFS_LAYER_TRANSPARENT}, - {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} + {SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP} }; NTSTATUS vfs_acl_xattr_init(void) diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c index 275c2f53c4..d972828ba9 100644 --- a/source3/modules/vfs_default.c +++ b/source3/modules/vfs_default.c @@ -596,7 +596,7 @@ static int vfswrap_chown(vfs_handle_struct *handle, const char *path, uid_t uid, int result; START_PROFILE(syscall_chown); - result = sys_chown(path, uid, gid); + result = chown(path, uid, gid); END_PROFILE(syscall_chown); return result; } @@ -621,7 +621,7 @@ static int vfswrap_lchown(vfs_handle_struct *handle, const char *path, uid_t uid int result; START_PROFILE(syscall_lchown); - result = sys_lchown(path, uid, gid); + result = lchown(path, uid, gid); END_PROFILE(syscall_lchown); return result; } @@ -869,7 +869,7 @@ static int vfswrap_symlink(vfs_handle_struct *handle, const char *oldpath, cons int result; START_PROFILE(syscall_symlink); - result = sys_symlink(oldpath, newpath); + result = symlink(oldpath, newpath); END_PROFILE(syscall_symlink); return result; } @@ -879,7 +879,7 @@ static int vfswrap_readlink(vfs_handle_struct *handle, const char *path, char * int result; START_PROFILE(syscall_readlink); - result = sys_readlink(path, buf, bufsiz); + result = readlink(path, buf, bufsiz); END_PROFILE(syscall_readlink); return result; } @@ -889,7 +889,7 @@ static int vfswrap_link(vfs_handle_struct *handle, const char *oldpath, const c int result; START_PROFILE(syscall_link); - result = sys_link(oldpath, newpath); + result = link(oldpath, newpath); END_PROFILE(syscall_link); return result; } @@ -909,7 +909,7 @@ static char *vfswrap_realpath(vfs_handle_struct *handle, const char *path, char char *result; START_PROFILE(syscall_realpath); - result = sys_realpath(path, resolved_path); + result = realpath(path, resolved_path); END_PROFILE(syscall_realpath); return result; } diff --git a/source3/modules/vfs_netatalk.c b/source3/modules/vfs_netatalk.c index 2cc4a6c4ba..ca7085ca18 100644 --- a/source3/modules/vfs_netatalk.c +++ b/source3/modules/vfs_netatalk.c @@ -399,7 +399,7 @@ static int atalk_lchown(struct vfs_handle_struct *handle, const char *path, uid_ goto exit_lchown; } - sys_lchown(adbl_path, uid, gid); + lchown(adbl_path, uid, gid); exit_lchown: talloc_destroy(ctx); diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index adc331cc3e..d1ab3aaacb 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -803,12 +803,12 @@ static bool open_sockets(bool isdaemon, int port) sys_srandom(time(NULL) ^ sys_getpid()); if (!override_logfile) { - char *logfile = NULL; - if (asprintf(&logfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) { + char *lfile = NULL; + if (asprintf(&lfile, "%s/log.nmbd", get_dyn_LOGFILEBASE()) < 0) { exit(1); } - lp_set_logfile(logfile); - SAFE_FREE(logfile); + lp_set_logfile(lfile); + SAFE_FREE(lfile); } fault_setup((void (*)(void *))fault_continue ); diff --git a/source3/nsswitch/winbind_struct_protocol.h b/source3/nsswitch/winbind_struct_protocol.h index ff52dbddaf..169b4a8c95 100644 --- a/source3/nsswitch/winbind_struct_protocol.h +++ b/source3/nsswitch/winbind_struct_protocol.h @@ -202,7 +202,9 @@ typedef struct winbindd_gr { #define WBFLAG_IS_PRIVILEGED 0x00000400 /* not used */ /* Flag to say this is a winbindd internal send - don't recurse. */ #define WBFLAG_RECURSE 0x00000800 - +/* Flag to tell winbind the NTLMv2 blob is too big for the struct and is in the + * extra_data field */ +#define WBFLAG_BIG_NTLMV2_BLOB 0x00010000 #define WINBINDD_MAX_EXTRA_DATA (128*1024) diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index d91d34d29b..217957ab37 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -4899,7 +4899,7 @@ static void init_globals(bool first_time_only) Globals.bWinbindTrustedDomainsOnly = False; Globals.bWinbindNestedGroups = True; Globals.winbind_expand_groups = 1; - Globals.szWinbindNssInfo = str_list_make(NULL, "template", NULL); + Globals.szWinbindNssInfo = str_list_make_v3(talloc_autofree_context(), "template", NULL); Globals.bWinbindRefreshTickets = False; Globals.bWinbindOfflineLogon = False; @@ -5418,7 +5418,6 @@ FN_GLOBAL_INTEGER(lp_client_ldap_sasl_wrapping, &Globals.client_ldap_sasl_wrappi static int map_parameter(const char *pszParmName); static int map_parameter_canonical(const char *pszParmName, bool *inverse); -static bool set_boolean(bool *pb, const char *pszParmValue); static const char *get_boolean(bool bool_value); static int getservicebyname(const char *pszServiceName, struct service *pserviceDest); @@ -5532,7 +5531,7 @@ static bool lp_bool(const char *s) return False; } - if (!set_boolean(&ret,s)) { + if (!set_boolean(s, &ret)) { DEBUG(0,("lp_bool(%s): value is not boolean!\n",s)); return False; } @@ -5616,7 +5615,7 @@ const char **lp_parm_string_list(int snum, const char *type, const char *option, return (const char **)def; if (data->list==NULL) { - data->list = str_list_make(NULL, data->value, NULL); + data->list = str_list_make_v3(talloc_autofree_context(), data->value, NULL); } return (const char **)data->list; @@ -6315,48 +6314,12 @@ void show_parameter_list(void) } /*************************************************************************** - Set a boolean variable from the text value stored in the passed string. - Returns True in success, False if the passed string does not correctly - represent a boolean. -***************************************************************************/ - -static bool set_boolean(bool *pb, const char *pszParmValue) -{ - bool bRetval; - bool value; - - bRetval = True; - value = False; - if (strwicmp(pszParmValue, "yes") == 0 || - strwicmp(pszParmValue, "true") == 0 || - strwicmp(pszParmValue, "1") == 0) - value = True; - else if (strwicmp(pszParmValue, "no") == 0 || - strwicmp(pszParmValue, "False") == 0 || - strwicmp(pszParmValue, "0") == 0) - value = False; - else { - DEBUG(2, - ("ERROR: Badly formed boolean in configuration file: \"%s\".\n", - pszParmValue)); - bRetval = False; - } - - if ((pb != NULL) && (bRetval != False)) { - *pb = value; - } - - return (bRetval); -} - - -/*************************************************************************** Check if a given string correctly represents a boolean value. ***************************************************************************/ bool lp_string_is_valid_boolean(const char *parm_value) { - return set_boolean(NULL, parm_value); + return set_boolean(parm_value, NULL); } /*************************************************************************** @@ -6381,7 +6344,7 @@ bool lp_invert_boolean(const char *str, const char **inverse_str) { bool val; - if (!set_boolean(&val, str)) { + if (!set_boolean(str, &val)) { return False; } @@ -6399,7 +6362,7 @@ bool lp_canonicalize_boolean(const char *str, const char**canon_str) { bool val; - if (!set_boolean(&val, str)) { + if (!set_boolean(str, &val)) { return False; } @@ -6606,7 +6569,7 @@ static struct smbconf_ctx *lp_smbconf_ctx(void) werr = smbconf_init(NULL, &conf_ctx, "registry:"); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("error initializing registry configuration: " - "%s\n", dos_errstr(werr))); + "%s\n", win_errstr(werr))); conf_ctx = NULL; } } @@ -6896,7 +6859,7 @@ static bool handle_netbios_scope(int snum, const char *pszParmValue, char **ptr) static bool handle_netbios_aliases(int snum, const char *pszParmValue, char **ptr) { TALLOC_FREE(Globals.szNetbiosAliases); - Globals.szNetbiosAliases = str_list_make(NULL, pszParmValue, NULL); + Globals.szNetbiosAliases = str_list_make_v3(talloc_autofree_context(), pszParmValue, NULL); return set_netbios_aliases((const char **)Globals.szNetbiosAliases); } @@ -7298,8 +7261,8 @@ bool lp_do_parameter(int snum, const char *pszParmName, const char *pszParmValue case P_LIST: TALLOC_FREE(*((char ***)parm_ptr)); - *(char ***)parm_ptr = str_list_make( - NULL, pszParmValue, NULL); + *(char ***)parm_ptr = str_list_make_v3( + talloc_autofree_context(), pszParmValue, NULL); break; case P_STRING: diff --git a/source3/passdb/passdb.c b/source3/passdb/passdb.c index 60699615f0..8367d6a9ad 100644 --- a/source3/passdb/passdb.c +++ b/source3/passdb/passdb.c @@ -665,7 +665,7 @@ NTSTATUS local_password_change(const char *user_name, DEBUGLEVEL = 1; } - if ( !(pwd = getpwnam_alloc( NULL, user_name)) ) { + if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), user_name)) ) { return NT_STATUS_NO_SUCH_USER; } diff --git a/source3/passdb/pdb_interface.c b/source3/passdb/pdb_interface.c index 2a1024cc56..6fe105854f 100644 --- a/source3/passdb/pdb_interface.c +++ b/source3/passdb/pdb_interface.c @@ -242,7 +242,7 @@ bool guest_user_info( struct samu *user ) NTSTATUS result; const char *guestname = lp_guestaccount(); - if ( !(pwd = getpwnam_alloc( NULL, guestname ) ) ) { + if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), guestname ) ) ) { DEBUG(0,("guest_user_info: Unable to locate guest account [%s]!\n", guestname)); return False; @@ -1150,7 +1150,9 @@ static NTSTATUS pdb_default_rename_sam_account (struct pdb_methods *methods, str static NTSTATUS pdb_default_update_login_attempts (struct pdb_methods *methods, struct samu *newpwd, bool success) { - return NT_STATUS_NOT_IMPLEMENTED; + /* Only the pdb_nds backend implements this, by + * default just return ok. */ + return NT_STATUS_OK; } static NTSTATUS pdb_default_get_account_policy(struct pdb_methods *methods, int policy_index, uint32 *value) @@ -2014,7 +2016,7 @@ NTSTATUS make_pdb_method( struct pdb_methods **methods ) { /* allocate memory for the structure as its own talloc CTX */ - if ( !(*methods = TALLOC_ZERO_P(NULL, struct pdb_methods) ) ) { + if ( !(*methods = TALLOC_ZERO_P(talloc_autofree_context(), struct pdb_methods) ) ) { return NT_STATUS_NO_MEMORY; } diff --git a/source3/passdb/util_unixsids.c b/source3/passdb/util_unixsids.c index 1b674d02a2..ad4e70256d 100644 --- a/source3/passdb/util_unixsids.c +++ b/source3/passdb/util_unixsids.c @@ -56,7 +56,7 @@ bool lookup_unix_user_name(const char *name, DOM_SID *sid) { struct passwd *pwd; - pwd = getpwnam_alloc(NULL, name); + pwd = getpwnam_alloc(talloc_autofree_context(), name); if (pwd == NULL) { return False; } diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 41383a0a57..11370272a2 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -659,7 +659,7 @@ bool nt_printing_init(struct messaging_context *msg_ctx) if ( lp_security() == SEC_ADS ) { win_rc = check_published_printers(); if (!W_ERROR_IS_OK(win_rc)) - DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", dos_errstr(win_rc))); + DEBUG(0, ("nt_printing_init: error checking published printers: %s\n", win_errstr(win_rc))); } return True; @@ -4749,7 +4749,7 @@ static WERROR get_a_printer_internal( Printer_entry *print_hnd, NT_PRINTER_INFO_ if ( !W_ERROR_IS_OK(result) ) { TALLOC_FREE( *pp_printer ); DEBUG(10,("get_a_printer: [%s] level %u returning %s\n", - sharename, (unsigned int)level, dos_errstr(result))); + sharename, (unsigned int)level, win_errstr(result))); return result; } diff --git a/source3/registry/reg_api.c b/source3/registry/reg_api.c index e9a7145255..30ad3d9751 100644 --- a/source3/registry/reg_api.c +++ b/source3/registry/reg_api.c @@ -1117,7 +1117,7 @@ static WERROR reg_deletekey_recursive_internal(TALLOC_CTX *ctx, if (!W_ERROR_EQUAL(WERR_NO_MORE_ITEMS, werr)) { DEBUG(1, ("reg_deletekey_recursive_internal: " "Error enumerating subkeys: %s\n", - dos_errstr(werr))); + win_errstr(werr))); goto done; } diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 6f4c614b9a..a9bb7b1730 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -963,7 +963,7 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) werr = regsubkey_ctr_addkey(ctr, subkeyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " - "failed: %s\n", dos_errstr(werr))); + "failed: %s\n", win_errstr(werr))); goto done; } } diff --git a/source3/registry/reg_init_basic.c b/source3/registry/reg_init_basic.c index c5e2c346b0..60dcabdcf2 100644 --- a/source3/registry/reg_init_basic.c +++ b/source3/registry/reg_init_basic.c @@ -29,14 +29,14 @@ WERROR registry_init_common(void) werr = regdb_init(); if (!W_ERROR_IS_OK(werr)) { DEBUG(0, ("Failed to initialize the registry: %s\n", - dos_errstr(werr))); + win_errstr(werr))); goto done; } werr = reghook_cache_init(); if (!W_ERROR_IS_OK(werr)) { DEBUG(0, ("Failed to initialize the reghook cache: %s\n", - dos_errstr(werr))); + win_errstr(werr))); } done: diff --git a/source3/registry/reg_init_smbconf.c b/source3/registry/reg_init_smbconf.c index 43a5be025d..7ba53cd367 100644 --- a/source3/registry/reg_init_smbconf.c +++ b/source3/registry/reg_init_smbconf.c @@ -87,14 +87,14 @@ WERROR registry_init_smbconf(const char *keyname) werr = init_registry_key(keyname); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Failed to initialize registry key '%s': %s\n", - keyname, dos_errstr(werr))); + keyname, win_errstr(werr))); goto done; } werr = reghook_cache_add(keyname, &smbconf_reg_ops); if (!W_ERROR_IS_OK(werr)) { DEBUG(1, ("Failed to add smbconf reghooks to reghook cache: " - "%s\n", dos_errstr(werr))); + "%s\n", win_errstr(werr))); goto done; } diff --git a/source3/rpc_client/init_netlogon.c b/source3/rpc_client/init_netlogon.c index e4c39e739e..4318a94076 100644 --- a/source3/rpc_client/init_netlogon.c +++ b/source3/rpc_client/init_netlogon.c @@ -172,7 +172,8 @@ static NTSTATUS nt_token_to_group_list(TALLOC_CTX *mem_ctx, *****************************************************************************/ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, - uint8_t pipe_session_key[16], + uint8_t *pipe_session_key, + size_t pipe_session_key_len, struct netr_SamInfo3 *sam3) { struct samu *sampw; @@ -203,6 +204,13 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, user_sid = pdb_get_user_sid(sampw); group_sid = pdb_get_group_sid(sampw); + if (pipe_session_key && pipe_session_key_len != 16) { + DEBUG(0,("serverinfo_to_SamInfo3: invalid " + "pipe_session_key_len[%u] != 16\n", + pipe_session_key_len)); + return NT_STATUS_INTERNAL_ERROR; + } + if ((user_sid == NULL) || (group_sid == NULL)) { DEBUG(1, ("_netr_LogonSamLogon: User without group or user SID\n")); return NT_STATUS_UNSUCCESSFUL; @@ -248,14 +256,18 @@ NTSTATUS serverinfo_to_SamInfo3(struct auth_serversupplied_info *server_info, server_info->user_session_key.data, MIN(sizeof(user_session_key.key), server_info->user_session_key.length)); - SamOEMhash(user_session_key.key, pipe_session_key, 16); + if (pipe_session_key) { + SamOEMhash(user_session_key.key, pipe_session_key, 16); + } } if (server_info->lm_session_key.length) { memcpy(lm_session_key.key, server_info->lm_session_key.data, MIN(sizeof(lm_session_key.key), server_info->lm_session_key.length)); - SamOEMhash(lm_session_key.key, pipe_session_key, 8); + if (pipe_session_key) { + SamOEMhash(lm_session_key.key, pipe_session_key, 8); + } } groups.count = num_gids; diff --git a/source3/rpc_parse/parse_prs.c b/source3/rpc_parse/parse_prs.c index 504cebbb9d..a0d3ed7397 100644 --- a/source3/rpc_parse/parse_prs.c +++ b/source3/rpc_parse/parse_prs.c @@ -843,7 +843,7 @@ bool prs_werror(const char *name, prs_struct *ps, int depth, WERROR *status) } DEBUG(5,("%s%04x %s: %s\n", tab_depth(5,depth), ps->data_offset, name, - dos_errstr(*status))); + win_errstr(*status))); ps->data_offset += sizeof(uint32); diff --git a/source3/rpc_server/srv_eventlog_nt.c b/source3/rpc_server/srv_eventlog_nt.c index e56a2e9095..3c7469f3ef 100644 --- a/source3/rpc_server/srv_eventlog_nt.c +++ b/source3/rpc_server/srv_eventlog_nt.c @@ -456,14 +456,14 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info ) if ( !W_ERROR_IS_OK( wresult ) ) { DEBUG( 4, ( "sync_eventlog_params: Failed to open key [%s] (%s)\n", - path, dos_errstr( wresult ) ) ); + path, win_errstr( wresult ) ) ); return false; } wresult = reg_queryvalue(key, key, "Retention", &value); if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"Retention\": %s\n", - dos_errstr(wresult))); + win_errstr(wresult))); ret = false; goto done; } @@ -472,7 +472,7 @@ static bool sync_eventlog_params( EVENTLOG_INFO *info ) wresult = reg_queryvalue(key, key, "MaxSize", &value); if (!W_ERROR_IS_OK(wresult)) { DEBUG(4, ("Failed to query value \"MaxSize\": %s\n", - dos_errstr(wresult))); + win_errstr(wresult))); ret = false; goto done; } diff --git a/source3/rpc_server/srv_netlog_nt.c b/source3/rpc_server/srv_netlog_nt.c index 75fc99401e..45acd3ed48 100644 --- a/source3/rpc_server/srv_netlog_nt.c +++ b/source3/rpc_server/srv_netlog_nt.c @@ -981,7 +981,7 @@ NTSTATUS _netr_LogonSamLogon(pipes_struct *p, memcpy(pipe_session_key, p->auth.a_u.schannel_auth->sess_key, 16); } - status = serverinfo_to_SamInfo3(server_info, pipe_session_key, sam3); + status = serverinfo_to_SamInfo3(server_info, pipe_session_key, 16, sam3); TALLOC_FREE(server_info); return status; } diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index b892755396..d359b9b339 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -20,6 +20,7 @@ */ #include "includes.h" +#include "librpc/gen_ndr/ndr_named_pipe_auth.h" #undef DBGC_CLASS #define DBGC_CLASS DBGC_RPC_SRV @@ -944,6 +945,17 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx, struct np_proxy_state *result; struct sockaddr_un addr; char *socket_path; + const char *socket_dir; + + DATA_BLOB req_blob; + struct netr_SamInfo3 *info3; + struct named_pipe_auth_req req; + DATA_BLOB rep_blob; + uint8 rep_buf[20]; + struct named_pipe_auth_rep rep; + enum ndr_err_code ndr_err; + NTSTATUS status; + ssize_t written; result = talloc(mem_ctx, struct np_proxy_state); if (result == NULL) { @@ -961,8 +973,16 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx, ZERO_STRUCT(addr); addr.sun_family = AF_UNIX; - socket_path = talloc_asprintf(talloc_tos(), "%s/%s", - get_dyn_NCALRPCDIR(), "DEFAULT"); + socket_dir = lp_parm_const_string( + GLOBAL_SECTION_SNUM, "external_rpc_pipe", "socket_dir", + get_dyn_NCALRPCDIR()); + if (socket_dir == NULL) { + DEBUG(0, ("externan_rpc_pipe:socket_dir not set\n")); + goto fail; + } + + socket_path = talloc_asprintf(talloc_tos(), "%s/np/%s", + socket_dir, pipe_name); if (socket_path == NULL) { DEBUG(0, ("talloc_asprintf failed\n")); goto fail; @@ -970,11 +990,96 @@ static struct np_proxy_state *make_external_rpc_pipe_p(TALLOC_CTX *mem_ctx, strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path)); TALLOC_FREE(socket_path); + become_root(); if (sys_connect(result->fd, (struct sockaddr *)&addr) == -1) { + unbecome_root(); DEBUG(0, ("connect(%s) failed: %s\n", addr.sun_path, strerror(errno))); goto fail; } + unbecome_root(); + + info3 = talloc(talloc_tos(), struct netr_SamInfo3); + if (info3 == NULL) { + DEBUG(0, ("talloc failed\n")); + goto fail; + } + + status = serverinfo_to_SamInfo3(server_info, NULL, 0, info3); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(info3); + DEBUG(0, ("serverinfo_to_SamInfo3 failed: %s\n", + nt_errstr(status))); + goto fail; + } + + req.level = 1; + req.info.info1 = *info3; + + ndr_err = ndr_push_struct_blob( + &req_blob, talloc_tos(), NULL, &req, + (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_req); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(10, ("ndr_push_named_pipe_auth_req failed: %s\n", + ndr_errstr(ndr_err))); + goto fail; + } + + DEBUG(10, ("named_pipe_auth_req(client)[%u]\n", (uint32_t)req_blob.length)); + dump_data(10, req_blob.data, req_blob.length); + + written = write_data(result->fd, (char *)req_blob.data, + req_blob.length); + if (written == -1) { + DEBUG(3, ("Could not write auth req data to RPC server\n")); + goto fail; + } + + status = read_data(result->fd, (char *)rep_buf, sizeof(rep_buf)); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(3, ("Could not read auth result\n")); + goto fail; + } + + rep_blob = data_blob_const(rep_buf, sizeof(rep_buf)); + + DEBUG(10,("name_pipe_auth_rep(client)[%u]\n", (uint32_t)rep_blob.length)); + dump_data(10, rep_blob.data, rep_blob.length); + + ndr_err = ndr_pull_struct_blob( + &rep_blob, talloc_tos(), NULL, &rep, + (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_rep); + + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + DEBUG(0, ("ndr_pull_named_pipe_auth_rep failed: %s\n", + ndr_errstr(ndr_err))); + goto fail; + } + + if (rep.length != 16) { + DEBUG(0, ("req invalid length: %u != 16\n", + rep.length)); + goto fail; + } + + if (strcmp(NAMED_PIPE_AUTH_MAGIC, rep.magic) != 0) { + DEBUG(0, ("req invalid magic: %s != %s\n", + rep.magic, NAMED_PIPE_AUTH_MAGIC)); + goto fail; + } + + if (!NT_STATUS_IS_OK(rep.status)) { + DEBUG(0, ("req failed: %s\n", + nt_errstr(rep.status))); + goto fail; + } + + if (rep.level != 1) { + DEBUG(0, ("req invalid level: %u != 1\n", + rep.level)); + goto fail; + } return result; @@ -1046,7 +1151,7 @@ NTSTATUS np_open(struct smb_request *smb_req, struct connection_struct *conn, return NT_STATUS_OK; } -NTSTATUS np_write(struct files_struct *fsp, uint8_t *data, size_t len, +NTSTATUS np_write(struct files_struct *fsp, const uint8_t *data, size_t len, ssize_t *nwritten) { if (!fsp_is_np(fsp)) { diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index 97da3a4f3d..62ac1cb5c3 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -38,13 +38,16 @@ #define SAMR_USR_RIGHTS_WRITE_PW \ ( READ_CONTROL_ACCESS | \ - SA_RIGHT_USER_CHANGE_PASSWORD | \ - SA_RIGHT_USER_SET_LOC_COM ) + SAMR_USER_ACCESS_CHANGE_PASSWORD | \ + SAMR_USER_ACCESS_SET_LOC_COM) #define SAMR_USR_RIGHTS_CANT_WRITE_PW \ - ( READ_CONTROL_ACCESS | SA_RIGHT_USER_SET_LOC_COM ) + ( READ_CONTROL_ACCESS | SAMR_USER_ACCESS_SET_LOC_COM ) #define DISP_INFO_CACHE_TIMEOUT 10 +#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */ +#define MAX_SAM_ENTRIES_W95 50 + typedef struct disp_info { DOM_SID sid; /* identify which domain this is. */ bool builtin_domain; /* Quick flag to check if this is the builtin domain. */ @@ -91,7 +94,7 @@ static const struct generic_mapping usr_generic_mapping = { static const struct generic_mapping usr_nopwchange_generic_mapping = { GENERIC_RIGHTS_USER_READ, GENERIC_RIGHTS_USER_WRITE, - GENERIC_RIGHTS_USER_EXECUTE & ~SA_RIGHT_USER_CHANGE_PASSWORD, + GENERIC_RIGHTS_USER_EXECUTE & ~SAMR_USER_ACCESS_CHANGE_PASSWORD, GENERIC_RIGHTS_USER_ALL_ACCESS}; static const struct generic_mapping grp_generic_mapping = { GENERIC_RIGHTS_GROUP_READ, @@ -622,7 +625,7 @@ NTSTATUS _samr_OpenDomain(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(info->acc_granted, - SA_RIGHT_SAM_OPEN_DOMAIN, + SAMR_ACCESS_OPEN_DOMAIN, "_samr_OpenDomain" ); if ( !NT_STATUS_IS_OK(status) ) @@ -791,7 +794,7 @@ NTSTATUS _samr_SetSecurity(pipes_struct *p, if (sid_equal(&pol_sid, &dacl->aces[i].trustee)) { ret = pdb_set_pass_can_change(sampass, (dacl->aces[i].access_mask & - SA_RIGHT_USER_CHANGE_PASSWORD) ? + SAMR_USER_ACCESS_CHANGE_PASSWORD) ? True: False); break; } @@ -803,7 +806,7 @@ NTSTATUS _samr_SetSecurity(pipes_struct *p, } status = access_check_samr_function(acc_granted, - SA_RIGHT_USER_SET_ATTRIBUTES, + SAMR_USER_ACCESS_SET_ATTRIBUTES, "_samr_SetSecurity"); if (NT_STATUS_IS_OK(status)) { become_root(); @@ -990,7 +993,7 @@ NTSTATUS _samr_EnumDomainUsers(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_EnumDomainUsers"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1129,7 +1132,7 @@ NTSTATUS _samr_EnumDomainGroups(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_EnumDomainGroups"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1209,7 +1212,7 @@ NTSTATUS _samr_EnumDomainAliases(pipes_struct *p, sid_string_dbg(&info->sid))); status = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_EnumDomainAliases"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1482,7 +1485,7 @@ NTSTATUS _samr_QueryDisplayInfo(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_QueryDisplayInfo"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -1737,7 +1740,7 @@ NTSTATUS _samr_QueryAliasInfo(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_ALIAS_LOOKUP_INFO, + SAMR_ALIAS_ACCESS_LOOKUP_INFO, "_samr_QueryAliasInfo"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -2062,8 +2065,8 @@ NTSTATUS _samr_LookupRids(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, - "_samr__LookupRids"); + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, + "_samr_LookupRids"); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -2146,7 +2149,7 @@ NTSTATUS _samr_OpenUser(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; nt_status = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_OPEN_ACCOUNT, + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_OpenUser" ); if ( !NT_STATUS_IS_OK(nt_status) ) @@ -2641,7 +2644,7 @@ NTSTATUS _samr_QueryUserInfo(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_OPEN_ACCOUNT, + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_QueryUserInfo"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -2764,7 +2767,7 @@ NTSTATUS _samr_GetGroupsForUser(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; result = access_check_samr_function(acc_granted, - SA_RIGHT_USER_GET_GROUPS, + SAMR_USER_ACCESS_GET_GROUPS, "_samr_GetGroupsForUser"); if (!NT_STATUS_IS_OK(result)) { return result; @@ -2891,7 +2894,7 @@ NTSTATUS _samr_QueryDomainInfo(pipes_struct *p, } status = access_check_samr_function(info->acc_granted, - SA_RIGHT_SAM_OPEN_DOMAIN, + SAMR_ACCESS_OPEN_DOMAIN, "_samr_QueryDomainInfo" ); if ( !NT_STATUS_IS_OK(status) ) @@ -3147,7 +3150,7 @@ NTSTATUS _samr_CreateUser2(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; nt_status = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_CREATE_USER, + SAMR_DOMAIN_ACCESS_CREATE_USER, "_samr_CreateUser2"); if (!NT_STATUS_IS_OK(nt_status)) { return nt_status; @@ -3284,14 +3287,14 @@ NTSTATUS _samr_Connect(pipes_struct *p, if ((info = get_samr_info_by_sid(NULL)) == NULL) return NT_STATUS_NO_MEMORY; - /* don't give away the farm but this is probably ok. The SA_RIGHT_SAM_ENUM_DOMAINS + /* don't give away the farm but this is probably ok. The SAMR_ACCESS_ENUM_DOMAINS was observed from a win98 client trying to enumerate users (when configured user level access control on shares) --jerry */ map_max_allowed_access(p->pipe_user.nt_user_token, &des_access); se_map_generic( &des_access, &sam_generic_mapping ); - info->acc_granted = des_access & (SA_RIGHT_SAM_ENUM_DOMAINS|SA_RIGHT_SAM_OPEN_DOMAIN); + info->acc_granted = des_access & (SAMR_ACCESS_ENUM_DOMAINS|SAMR_ACCESS_OPEN_DOMAIN); /* get a (unique) handle. open a policy on it. */ if (!create_policy_hnd(p, r->out.connect_handle, free_samr_info, (void *)info)) @@ -3474,11 +3477,11 @@ NTSTATUS _samr_LookupDomain(pipes_struct *p, if (!find_policy_by_hnd(p, r->in.connect_handle, (void**)(void *)&info)) return NT_STATUS_INVALID_HANDLE; - /* win9x user manager likes to use SA_RIGHT_SAM_ENUM_DOMAINS here. + /* win9x user manager likes to use SAMR_ACCESS_ENUM_DOMAINS here. Reverted that change so we will work with RAS servers again */ status = access_check_samr_function(info->acc_granted, - SA_RIGHT_SAM_OPEN_DOMAIN, + SAMR_ACCESS_OPEN_DOMAIN, "_samr_LookupDomain"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -3524,7 +3527,7 @@ NTSTATUS _samr_EnumDomains(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(info->acc_granted, - SA_RIGHT_SAM_ENUM_DOMAINS, + SAMR_ACCESS_ENUM_DOMAINS, "_samr_EnumDomains"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -3582,7 +3585,7 @@ NTSTATUS _samr_OpenAlias(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_OPEN_ACCOUNT, + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_OpenAlias"); if ( !NT_STATUS_IS_OK(status) ) @@ -4109,9 +4112,9 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, } /* This is tricky. A WinXP domain join sets - (SA_RIGHT_USER_SET_PASSWORD|SA_RIGHT_USER_SET_ATTRIBUTES|SA_RIGHT_USER_ACCT_FLAGS_EXPIRY) + (SAMR_USER_ACCESS_SET_PASSWORD|SAMR_USER_ACCESS_SET_ATTRIBUTES|SAMR_USER_ACCESS_GET_ATTRIBUTES) The MMC lusrmgr plugin includes these perms and more in the SamrOpenUser(). But the - standard Win32 API calls just ask for SA_RIGHT_USER_SET_PASSWORD in the SamrOpenUser(). + standard Win32 API calls just ask for SAMR_USER_ACCESS_SET_PASSWORD in the SamrOpenUser(). This should be enough for levels 18, 24, 25,& 26. Info level 23 can set more so we'll use the set from the WinXP join as the basis. */ @@ -4120,12 +4123,12 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, case 24: case 25: case 26: - acc_required = SA_RIGHT_USER_SET_PASSWORD; + acc_required = SAMR_USER_ACCESS_SET_PASSWORD; break; default: - acc_required = SA_RIGHT_USER_SET_PASSWORD | - SA_RIGHT_USER_SET_ATTRIBUTES | - SA_RIGHT_USER_ACCT_FLAGS_EXPIRY; + acc_required = SAMR_USER_ACCESS_SET_PASSWORD | + SAMR_USER_ACCESS_SET_ATTRIBUTES | + SAMR_USER_ACCESS_GET_ATTRIBUTES; break; } @@ -4342,10 +4345,10 @@ NTSTATUS _samr_GetAliasMembership(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; ntstatus1 = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_LOOKUP_ALIAS_BY_MEM, + SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS, "_samr_GetAliasMembership"); ntstatus2 = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_OPEN_ACCOUNT, + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_GetAliasMembership"); if (!NT_STATUS_IS_OK(ntstatus1) || !NT_STATUS_IS_OK(ntstatus2)) { @@ -4412,7 +4415,7 @@ NTSTATUS _samr_GetMembersInAlias(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_ALIAS_GET_MEMBERS, + SAMR_ALIAS_ACCESS_GET_MEMBERS, "_samr_GetMembersInAlias"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4480,7 +4483,7 @@ NTSTATUS _samr_QueryGroupMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_GROUP_GET_MEMBERS, + SAMR_GROUP_ACCESS_GET_MEMBERS, "_samr_QueryGroupMember"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4544,7 +4547,7 @@ NTSTATUS _samr_AddAliasMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_ALIAS_ADD_MEMBER, + SAMR_ALIAS_ACCESS_ADD_MEMBER, "_samr_AddAliasMember"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4593,7 +4596,7 @@ NTSTATUS _samr_DeleteAliasMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_ALIAS_REMOVE_MEMBER, + SAMR_ALIAS_ACCESS_REMOVE_MEMBER, "_samr_DeleteAliasMember"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4644,7 +4647,7 @@ NTSTATUS _samr_AddGroupMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_GROUP_ADD_MEMBER, + SAMR_GROUP_ACCESS_ADD_MEMBER, "_samr_AddGroupMember"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4704,7 +4707,7 @@ NTSTATUS _samr_DeleteGroupMember(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_GROUP_REMOVE_MEMBER, + SAMR_GROUP_ACCESS_REMOVE_MEMBER, "_samr_DeleteGroupMember"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -4985,7 +4988,7 @@ NTSTATUS _samr_CreateDomainGroup(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_CREATE_GROUP, + SAMR_DOMAIN_ACCESS_CREATE_GROUP, "_samr_CreateDomainGroup"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -5067,7 +5070,7 @@ NTSTATUS _samr_CreateDomAlias(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; result = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_CREATE_ALIAS, + SAMR_DOMAIN_ACCESS_CREATE_ALIAS, "_samr_CreateDomAlias"); if (!NT_STATUS_IS_OK(result)) { return result; @@ -5159,7 +5162,7 @@ NTSTATUS _samr_QueryGroupInfo(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_GROUP_LOOKUP_INFO, + SAMR_GROUP_ACCESS_LOOKUP_INFO, "_samr_QueryGroupInfo"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -5265,7 +5268,7 @@ NTSTATUS _samr_SetGroupInfo(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_GROUP_SET_INFO, + SAMR_GROUP_ACCESS_SET_INFO, "_samr_SetGroupInfo"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -5330,7 +5333,7 @@ NTSTATUS _samr_SetAliasInfo(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_ALIAS_SET_INFO, + SAMR_ALIAS_ACCESS_SET_INFO, "_samr_SetAliasInfo"); if (!NT_STATUS_IS_OK(status)) { return status; @@ -5474,7 +5477,7 @@ NTSTATUS _samr_OpenGroup(pipes_struct *p, return NT_STATUS_INVALID_HANDLE; status = access_check_samr_function(acc_granted, - SA_RIGHT_DOMAIN_OPEN_ACCOUNT, + SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT, "_samr_OpenGroup"); if ( !NT_STATUS_IS_OK(status) ) @@ -5628,11 +5631,11 @@ NTSTATUS _samr_SetDomainInfo(pipes_struct *p, * levels here, but we're really just looking for * GENERIC_RIGHTS_DOMAIN_WRITE access. Unfortunately * this maps to different specific bits. So - * assume if we have SA_RIGHT_DOMAIN_SET_INFO_1 + * assume if we have SAMR_DOMAIN_ACCESS_SET_INFO_1 * set we are ok. */ result = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_SET_INFO_1, + SAMR_DOMAIN_ACCESS_SET_INFO_1, "_samr_SetDomainInfo"); if (!NT_STATUS_IS_OK(result)) @@ -5705,7 +5708,7 @@ NTSTATUS _samr_GetDisplayEnumerationIndex(pipes_struct *p, } status = access_check_samr_function(info->acc_granted, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, "_samr_GetDisplayEnumerationIndex"); if (!NT_STATUS_IS_OK(status)) { return status; diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index cafe9fc9af..577f7f1ded 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -171,7 +171,7 @@ static void srv_spoolss_replycloseprinter(int snum, POLICY_HND *handle) if (!W_ERROR_IS_OK(result)) DEBUG(0,("srv_spoolss_replycloseprinter: reply_close_printer failed [%s].\n", - dos_errstr(result))); + win_errstr(result))); /* if it's the last connection, deconnect the IPC$ share */ if (smb_connections==1) { @@ -541,7 +541,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) result = get_a_printer_search( NULL, &printer, 2, sname ); if ( !W_ERROR_IS_OK(result) ) { DEBUG(0,("set_printer_hnd_name: failed to lookup printer [%s] -- result [%s]\n", - sname, dos_errstr(result))); + sname, win_errstr(result))); continue; } @@ -1284,7 +1284,7 @@ void do_drv_upgrade_printer(struct messaging_context *msg, result = mod_a_printer(printer, 2); if (!W_ERROR_IS_OK(result)) { DEBUG(3,("do_drv_upgrade_printer: mod_a_printer() failed with status [%s]\n", - dos_errstr(result))); + win_errstr(result))); } } @@ -2677,7 +2677,7 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, if (!W_ERROR_IS_OK(result)) DEBUG(5,("srv_spoolss_reply_open_printer: Client RPC returned [%s]\n", - dos_errstr(result))); + win_errstr(result))); return (W_ERROR_IS_OK(result)); } @@ -5376,12 +5376,12 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, con ZERO_STRUCT(driver); status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); - DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) return WERR_INVALID_PRINTER_NAME; status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status))); #if 0 /* JERRY */ @@ -5401,7 +5401,7 @@ static WERROR construct_printer_driver_info_3(DRIVER_INFO_3 *info, int snum, con /* Yes - try again with a WinNT driver. */ version = 2; status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_3: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_3: status: %s\n", win_errstr(status))); } #endif @@ -5519,14 +5519,14 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, status=get_a_printer(NULL, &printer, 2, lp_const_servicename(snum) ); - DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) return WERR_INVALID_PRINTER_NAME; status = get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) { @@ -5542,7 +5542,7 @@ static WERROR construct_printer_driver_info_6(DRIVER_INFO_6 *info, int snum, /* Yes - try again with a WinNT driver. */ version = 2; status=get_a_printer_driver(&driver, 3, printer->info_2->drivername, architecture, version); - DEBUG(8,("construct_printer_driver_info_6: status: %s\n", dos_errstr(status))); + DEBUG(8,("construct_printer_driver_info_6: status: %s\n", win_errstr(status))); if (!W_ERROR_IS_OK(status)) { free_a_printer(&printer,2); return WERR_UNKNOWN_PRINTER_DRIVER; @@ -7544,7 +7544,7 @@ static WERROR enumports_level_1(RPC_BUFFER *buffer, uint32 offered, uint32 *need if(numlines) { if((ports=SMB_MALLOC_ARRAY( PORT_INFO_1, numlines )) == NULL) { DEBUG(10,("Returning WERR_NOMEM [%s]\n", - dos_errstr(WERR_NOMEM))); + win_errstr(WERR_NOMEM))); TALLOC_FREE(qlines); return WERR_NOMEM; } diff --git a/source3/rpc_server/srv_wkssvc_nt.c b/source3/rpc_server/srv_wkssvc_nt.c index c96439cc1a..0a54b0dd3f 100644 --- a/source3/rpc_server/srv_wkssvc_nt.c +++ b/source3/rpc_server/srv_wkssvc_nt.c @@ -349,7 +349,7 @@ WERROR _wkssvc_NetrJoinDomain2(pipes_struct *p, if (!W_ERROR_IS_OK(werr)) { DEBUG(5,("_wkssvc_NetrJoinDomain2: libnet_Join failed with: %s\n", j->out.error_string ? j->out.error_string : - dos_errstr(werr))); + win_errstr(werr))); } TALLOC_FREE(j); @@ -415,7 +415,7 @@ WERROR _wkssvc_NetrUnjoinDomain2(pipes_struct *p, if (!W_ERROR_IS_OK(werr)) { DEBUG(5,("_wkssvc_NetrUnjoinDomain2: libnet_Unjoin failed with: %s\n", u->out.error_string ? u->out.error_string : - dos_errstr(werr))); + win_errstr(werr))); } TALLOC_FREE(u); diff --git a/source3/rpcclient/cmd_netlogon.c b/source3/rpcclient/cmd_netlogon.c index 6efa316cf4..9955d2d3fa 100644 --- a/source3/rpcclient/cmd_netlogon.c +++ b/source3/rpcclient/cmd_netlogon.c @@ -221,7 +221,7 @@ static WERROR cmd_netlogon_dsr_getdcname(struct rpc_pipe_client *cli, } printf("rpccli_netlogon_dsr_getdcname returned %s\n", - dos_errstr(werr)); + win_errstr(werr)); return werr; } @@ -1040,6 +1040,72 @@ static WERROR cmd_netlogon_getdcsitecoverage(struct rpc_pipe_client *cli, return werr; } +static NTSTATUS cmd_netlogon_database_redo(struct rpc_pipe_client *cli, + TALLOC_CTX *mem_ctx, int argc, + const char **argv) +{ + NTSTATUS status = NT_STATUS_UNSUCCESSFUL; + const char *server_name = cli->desthost; + uint32_t neg_flags = NETLOGON_NEG_AUTH2_ADS_FLAGS; + struct netr_Authenticator clnt_creds, srv_cred; + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + unsigned char trust_passwd_hash[16]; + uint32_t sec_channel_type = 0; + struct netr_ChangeLogEntry e; + uint32_t rid = 500; + + if (argc > 2) { + fprintf(stderr, "Usage: %s <user rid>\n", argv[0]); + return NT_STATUS_OK; + } + + if (argc == 2) { + sscanf(argv[1], "%d", &rid); + } + + if (!secrets_fetch_trust_account_password(lp_workgroup(), + trust_passwd_hash, + NULL, &sec_channel_type)) { + return NT_STATUS_UNSUCCESSFUL; + } + + status = rpccli_netlogon_setup_creds(cli, + server_name, /* server name */ + lp_workgroup(), /* domain */ + global_myname(), /* client name */ + global_myname(), /* machine account name */ + trust_passwd_hash, + sec_channel_type, + &neg_flags); + + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + netlogon_creds_client_step(cli->dc, &clnt_creds); + + ZERO_STRUCT(e); + + e.object_rid = rid; + e.db_index = SAM_DATABASE_DOMAIN; + e.delta_type = NETR_DELTA_USER; + + status = rpccli_netr_DatabaseRedo(cli, mem_ctx, + server_name, + global_myname(), + &clnt_creds, + &srv_cred, + e, + 0, /* is calculated automatically */ + &delta_enum_array); + + if (!netlogon_creds_client_check(cli->dc, &srv_cred.cred)) { + DEBUG(0,("credentials chain check failed\n")); + return NT_STATUS_ACCESS_DENIED; + } + + return status; +} /* List of commands exported by this module */ @@ -1067,6 +1133,7 @@ struct cmd_set netlogon_commands[] = { { "netrenumtrusteddomains", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomains, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" }, { "netrenumtrusteddomainsex", RPC_RTYPE_WERROR, NULL, cmd_netlogon_enumtrusteddomainsex, &ndr_table_netlogon.syntax_id, NULL, "Enumerate trusted domains", "" }, { "getdcsitecoverage", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcsitecoverage, &ndr_table_netlogon.syntax_id, NULL, "Get the Site-Coverage from a DC", "" }, + { "database_redo", RPC_RTYPE_NTSTATUS, cmd_netlogon_database_redo, NULL, &ndr_table_netlogon.syntax_id, NULL, "Replicate single object from a DC", "" }, { NULL } }; diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index 378ec891a7..26a73203b9 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -1539,7 +1539,7 @@ static WERROR cmd_spoolss_deletedriverex(struct rpc_pipe_client *cli, { if ( !W_ERROR_EQUAL(result, WERR_UNKNOWN_PRINTER_DRIVER) ) { printf ("Failed to remove driver %s for arch [%s] (version: %d): %s\n", - argv[1], archi_table[i].long_archi, archi_table[i].version, dos_errstr(result)); + argv[1], archi_table[i].long_archi, archi_table[i].version, win_errstr(result)); } } else @@ -2555,7 +2555,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, printf("Retrieving printer propertiesfor %s...", cli1->desthost); werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 2, &ctr1); if ( !W_ERROR_IS_OK(werror) ) { - printf("failed (%s)\n", dos_errstr(werror)); + printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); return False; } @@ -2564,7 +2564,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, POLICY_HND *hnd1, printf("Retrieving printer properties for %s...", cli2->desthost); werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 2, &ctr2); if ( !W_ERROR_IS_OK(werror) ) { - printf("failed (%s)\n", dos_errstr(werror)); + printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); return False; } @@ -2591,7 +2591,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("Retrieving printer security for %s...", cli1->desthost); werror = rpccli_spoolss_getprinter( cli1, mem_ctx, hnd1, 3, &ctr1); if ( !W_ERROR_IS_OK(werror) ) { - printf("failed (%s)\n", dos_errstr(werror)); + printf("failed (%s)\n", win_errstr(werror)); result = False; goto done; } @@ -2600,7 +2600,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, POLICY_HND *h printf("Retrieving printer security for %s...", cli2->desthost); werror = rpccli_spoolss_getprinter( cli2, mem_ctx, hnd2, 3, &ctr2); if ( !W_ERROR_IS_OK(werror) ) { - printf("failed (%s)\n", dos_errstr(werror)); + printf("failed (%s)\n", win_errstr(werror)); result = False; goto done; } @@ -2701,7 +2701,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, werror = rpccli_spoolss_open_printer_ex( cli, mem_ctx, printername_path, "", PRINTER_ALL_ACCESS, servername1, cli_server1->user_name, &hPrinter1); if ( !W_ERROR_IS_OK(werror) ) { - printf("failed (%s)\n", dos_errstr(werror)); + printf("failed (%s)\n", win_errstr(werror)); goto done; } printf("ok\n"); @@ -2717,7 +2717,7 @@ static WERROR cmd_spoolss_printercmp(struct rpc_pipe_client *cli, werror = rpccli_spoolss_open_printer_ex( cli2, mem_ctx, printername_path, "", PRINTER_ALL_ACCESS, servername2, cli_server2->user_name, &hPrinter2 ); if ( !W_ERROR_IS_OK(werror) ) { - printf("failed (%s)\n", dos_errstr(werror)); + printf("failed (%s)\n", win_errstr(werror)); goto done; } printf("ok\n"); diff --git a/source3/rpcclient/rpcclient.c b/source3/rpcclient/rpcclient.c index e4cdd9c3f3..61d8d7c485 100644 --- a/source3/rpcclient/rpcclient.c +++ b/source3/rpcclient/rpcclient.c @@ -669,7 +669,7 @@ static NTSTATUS do_cmd(struct cli_state *cli, wresult = cmd_entry->wfn(cmd_entry->rpc_pipe, mem_ctx, argc, (const char **) argv); /* print out the DOS error */ if (!W_ERROR_IS_OK(wresult)) { - printf( "result was %s\n", dos_errstr(wresult)); + printf( "result was %s\n", win_errstr(wresult)); } ntresult = W_ERROR_IS_OK(wresult)?NT_STATUS_OK:NT_STATUS_UNSUCCESSFUL; } diff --git a/source3/samba4.mk b/source3/samba4.mk index c3b6af10e4..1743431aa4 100644 --- a/source3/samba4.mk +++ b/source3/samba4.mk @@ -164,3 +164,82 @@ pythonmods:: $(PYTHON_PYS) $(PYTHON_SO) all:: bin/samba4 bin/regpatch4 bin/regdiff4 bin/regshell4 bin/regtree4 bin/smbclient4 torture:: bin/smbtorture4 everything:: $(patsubst %,%4,$(BINARIES)) + +SELFTEST4 = $(LD_LIBPATH_OVERRIDE) $(PERL) $(selftestdir)/selftest.pl --prefix=st4 \ + --builddir=$(builddir) --srcdir=$(samba4srcdir) \ + --expected-failures=$(samba4srcdir)/selftest/knownfail \ + --format=$(SELFTEST_FORMAT) \ + --exclude=$(samba4srcdir)/selftest/skip --testlist="$(samba4srcdir)/selftest/tests.sh|" \ + $(TEST4_OPTIONS) + +SELFTEST4_NOSLOW_OPTS = --exclude=$(samba4srcdir)/selftest/slow +SELFTEST4_QUICK_OPTS = $(SELFTEST4_NOSLOW_OPTS) --quick --include=$(samba4srcdir)/selftest/quick + +slowtest4:: everything + $(SELFTEST4) $(DEFAULT_TEST_OPTIONS) --immediate $(TESTS) + +test4:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) $(DEFAULT_TEST_OPTIONS) --immediate \ + $(TESTS) + +testone4:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) $(DEFAULT_TEST_OPTIONS) --one $(TESTS) + +test4-swrap:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --immediate $(TESTS) + +test4-swrap-pcap:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper-pcap --immediate $(TESTS) + +test4-swrap-keep-pcap:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper-keep-pcap --immediate $(TESTS) + +test4-noswrap:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate $(TESTS) + +quicktest4:: all + $(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --socket-wrapper --immediate $(TESTS) + +quicktestone4:: all + $(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --socket-wrapper --one $(TESTS) + +testenv4:: everything + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv + +testenv4-%:: everything + SELFTEST_TESTENV=$* $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv + +test4-%:: + $(MAKE) test TESTS=$* + +valgrindtest4:: valgrindtest-all + +valgrindtest4-quick:: all + SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ + $(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) + +valgrindtest4-all:: everything + SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) + +valgrindtest4-env:: everything + SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv + +gdbtest4:: gdbtest4-all + +gdbtest4-quick:: all + SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + $(SELFTEST4) $(SELFTEST4_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) + +gdbtest4-all:: everything + SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) + +gdbtest4-env:: everything + SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv + diff --git a/source3/services/services_db.c b/source3/services/services_db.c index 0f5264bcd8..dbd2da1c65 100644 --- a/source3/services/services_db.c +++ b/source3/services/services_db.c @@ -358,7 +358,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); SAFE_FREE(path); return; } @@ -400,7 +400,7 @@ static void add_new_svc_name( REGISTRY_KEY *key_parent, REGSUBKEY_CTR *subkeys, get_root_nt_token(), REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("add_new_svc_name: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); TALLOC_FREE( key_secdesc ); SAFE_FREE(path); return; @@ -455,7 +455,7 @@ void svcctl_init_keys( void ) if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_init_keys: key lookup failed! (%s)\n", - dos_errstr(wresult))); + win_errstr(wresult))); return; } @@ -519,7 +519,7 @@ SEC_DESC *svcctl_get_secdesc( TALLOC_CTX *ctx, const char *name, NT_USER_TOKEN * REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); goto done; } @@ -579,7 +579,7 @@ bool svcctl_set_secdesc( TALLOC_CTX *ctx, const char *name, SEC_DESC *sec_desc, REG_KEY_ALL ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_get_secdesc: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); SAFE_FREE(path); return False; } @@ -634,7 +634,7 @@ const char *svcctl_lookup_dispname(TALLOC_CTX *ctx, const char *name, NT_USER_TO REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_dispname: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); SAFE_FREE(path); goto fail; } @@ -684,7 +684,7 @@ const char *svcctl_lookup_description(TALLOC_CTX *ctx, const char *name, NT_USER REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_lookup_description: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); SAFE_FREE(path); return NULL; } @@ -728,7 +728,7 @@ REGVAL_CTR *svcctl_fetch_regvalues( const char *name, NT_USER_TOKEN *token ) REG_KEY_READ ); if ( !W_ERROR_IS_OK(wresult) ) { DEBUG(0,("svcctl_fetch_regvalues: key lookup failed! [%s] (%s)\n", - path, dos_errstr(wresult))); + path, win_errstr(wresult))); SAFE_FREE(path); return NULL; } diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index c3fd0a2bc0..8beed0744c 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -45,94 +45,52 @@ struct aio_extra { struct aio_extra *next, *prev; SMB_STRUCT_AIOCB acb; files_struct *fsp; - bool read_req; - uint16 mid; - char *inbuf; + struct smb_request *req; char *outbuf; + int (*handle_completion)(struct aio_extra *ex); }; -static struct aio_extra *aio_list_head; +static int handle_aio_read_complete(struct aio_extra *aio_ex); +static int handle_aio_write_complete(struct aio_extra *aio_ex); -/**************************************************************************** - Create the extended aio struct we must keep around for the lifetime - of the aio_read call. -*****************************************************************************/ +static struct aio_extra *aio_list_head; -static struct aio_extra *create_aio_ex_read(files_struct *fsp, size_t buflen, - uint16 mid) +static int aio_extra_destructor(struct aio_extra *aio_ex) { - struct aio_extra *aio_ex = SMB_MALLOC_P(struct aio_extra); - - if (!aio_ex) { - return NULL; - } - ZERO_STRUCTP(aio_ex); - /* The output buffer stored in the aio_ex is the start of - the smb return buffer. The buffer used in the acb - is the start of the reply data portion of that buffer. */ - aio_ex->outbuf = SMB_MALLOC_ARRAY(char, buflen); - if (!aio_ex->outbuf) { - SAFE_FREE(aio_ex); - return NULL; - } - DLIST_ADD(aio_list_head, aio_ex); - aio_ex->fsp = fsp; - aio_ex->read_req = True; - aio_ex->mid = mid; - return aio_ex; + DLIST_REMOVE(aio_list_head, aio_ex); + return 0; } /**************************************************************************** Create the extended aio struct we must keep around for the lifetime - of the aio_write call. + of the aio call. *****************************************************************************/ -static struct aio_extra *create_aio_ex_write(files_struct *fsp, - size_t inbuflen, - size_t outbuflen, - uint16 mid) +static struct aio_extra *create_aio_extra(files_struct *fsp, size_t buflen) { - struct aio_extra *aio_ex = SMB_MALLOC_P(struct aio_extra); + struct aio_extra *aio_ex = TALLOC_ZERO_P(NULL, struct aio_extra); if (!aio_ex) { return NULL; } - ZERO_STRUCTP(aio_ex); - /* We need space for an output reply of outbuflen bytes. */ - aio_ex->outbuf = SMB_MALLOC_ARRAY(char, outbuflen); - if (!aio_ex->outbuf) { - SAFE_FREE(aio_ex); - return NULL; - } + /* The output buffer stored in the aio_ex is the start of + the smb return buffer. The buffer used in the acb + is the start of the reply data portion of that buffer. */ - if (!(aio_ex->inbuf = SMB_MALLOC_ARRAY(char, inbuflen))) { - SAFE_FREE(aio_ex->outbuf); - SAFE_FREE(aio_ex); + aio_ex->outbuf = TALLOC_ARRAY(aio_ex, char, buflen); + if (!aio_ex->outbuf) { + TALLOC_FREE(aio_ex); return NULL; } - DLIST_ADD(aio_list_head, aio_ex); + talloc_set_destructor(aio_ex, aio_extra_destructor); aio_ex->fsp = fsp; - aio_ex->read_req = False; - aio_ex->mid = mid; return aio_ex; } /**************************************************************************** - Delete the extended aio struct. -*****************************************************************************/ - -static void delete_aio_ex(struct aio_extra *aio_ex) -{ - DLIST_REMOVE(aio_list_head, aio_ex); - SAFE_FREE(aio_ex->inbuf); - SAFE_FREE(aio_ex->outbuf); - SAFE_FREE(aio_ex); -} - -/**************************************************************************** - Given the aiocb struct find the extended aio struct containing it. + Given the mid find the extended aio struct containing it. *****************************************************************************/ static struct aio_extra *find_aio_ex(uint16 mid) @@ -140,7 +98,7 @@ static struct aio_extra *find_aio_ex(uint16 mid) struct aio_extra *p; for( p = aio_list_head; p; p = p->next) { - if (mid == p->mid) { + if (mid == p->req->mid) { return p; } } @@ -221,6 +179,7 @@ bool schedule_aio_read_and_X(connection_struct *conn, SMB_STRUCT_AIOCB *a; size_t bufsize; size_t min_aio_read_size = lp_aio_read_size(SNUM(conn)); + int ret; if (fsp->base_fsp != NULL) { /* No AIO on streams yet */ @@ -240,7 +199,7 @@ bool schedule_aio_read_and_X(connection_struct *conn, /* Only do this on non-chained and non-chaining reads not using the * write cache. */ - if (chain_size !=0 || (CVAL(req->inbuf,smb_vwv0) != 0xFF) + if (chain_size !=0 || (CVAL(req->vwv+0, 0) != 0xFF) || (lp_write_cache_size(SNUM(conn)) != 0) ) { return False; } @@ -257,43 +216,47 @@ bool schedule_aio_read_and_X(connection_struct *conn, bufsize = smb_size + 12 * 2 + smb_maxcnt; - if ((aio_ex = create_aio_ex_read(fsp, bufsize, req->mid)) == NULL) { + if ((aio_ex = create_aio_extra(fsp, bufsize)) == NULL) { DEBUG(10,("schedule_aio_read_and_X: malloc fail.\n")); return False; } + aio_ex->handle_completion = handle_aio_read_complete; - construct_reply_common((char *)req->inbuf, aio_ex->outbuf); + construct_reply_common_req(req, aio_ex->outbuf); srv_set_message(aio_ex->outbuf, 12, 0, True); SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */ a = &aio_ex->acb; /* Now set up the aio record for the read call. */ - + a->aio_fildes = fsp->fh->fd; a->aio_buf = smb_buf(aio_ex->outbuf); a->aio_nbytes = smb_maxcnt; a->aio_offset = startpos; a->aio_sigevent.sigev_notify = SIGEV_SIGNAL; a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO; - a->aio_sigevent.sigev_value.sival_int = aio_ex->mid; + a->aio_sigevent.sigev_value.sival_int = req->mid; become_root(); - if (SMB_VFS_AIO_READ(fsp,a) == -1) { + ret = SMB_VFS_AIO_READ(fsp, a); + unbecome_root(); + + if (ret == -1) { DEBUG(0,("schedule_aio_read_and_X: aio_read failed. " "Error %s\n", strerror(errno) )); - delete_aio_ex(aio_ex); - unbecome_root(); + TALLOC_FREE(aio_ex); return False; } - unbecome_root(); + + aio_ex->req = talloc_move(aio_ex, &req); DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, " "offset %.0f, len = %u (mid = %u)\n", fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt, - (unsigned int)aio_ex->mid )); + (unsigned int)aio_ex->req->mid )); - srv_defer_sign_response(aio_ex->mid); + srv_defer_sign_response(aio_ex->req->mid); outstanding_aio_calls++; return True; } @@ -310,9 +273,10 @@ bool schedule_aio_write_and_X(connection_struct *conn, { struct aio_extra *aio_ex; SMB_STRUCT_AIOCB *a; - size_t inbufsize, outbufsize; - bool write_through = BITSETW(req->inbuf+smb_vwv7,0); + size_t bufsize; + bool write_through = BITSETW(req->vwv+7,0); size_t min_aio_write_size = lp_aio_write_size(SNUM(conn)); + int ret; if (fsp->base_fsp != NULL) { /* No AIO on streams yet */ @@ -332,7 +296,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, /* Only do this on non-chained and non-chaining reads not using the * write cache. */ - if (chain_size !=0 || (CVAL(req->inbuf,smb_vwv0) != 0xFF) + if (chain_size !=0 || (CVAL(req->vwv+0, 0) != 0xFF) || (lp_write_cache_size(SNUM(conn)) != 0) ) { return False; } @@ -350,45 +314,43 @@ bool schedule_aio_write_and_X(connection_struct *conn, return False; } - inbufsize = smb_len(req->inbuf) + 4; - reply_outbuf(req, 6, 0); - outbufsize = smb_len(req->outbuf) + 4; - if (!(aio_ex = create_aio_ex_write(fsp, inbufsize, outbufsize, - req->mid))) { + bufsize = smb_size + 6*2; + + if (!(aio_ex = create_aio_extra(fsp, bufsize))) { DEBUG(0,("schedule_aio_write_and_X: malloc fail.\n")); return False; } + aio_ex->handle_completion = handle_aio_write_complete; - /* Copy the SMB header already setup in outbuf. */ - memcpy(aio_ex->inbuf, req->inbuf, inbufsize); - - /* Copy the SMB header already setup in outbuf. */ - memcpy(aio_ex->outbuf, req->outbuf, outbufsize); - TALLOC_FREE(req->outbuf); + construct_reply_common_req(req, aio_ex->outbuf); + srv_set_message(aio_ex->outbuf, 6, 0, True); SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */ a = &aio_ex->acb; /* Now set up the aio record for the write call. */ - + a->aio_fildes = fsp->fh->fd; - a->aio_buf = aio_ex->inbuf + (PTR_DIFF(data, req->inbuf)); + a->aio_buf = data; a->aio_nbytes = numtowrite; a->aio_offset = startpos; a->aio_sigevent.sigev_notify = SIGEV_SIGNAL; a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO; - a->aio_sigevent.sigev_value.sival_int = aio_ex->mid; + a->aio_sigevent.sigev_value.sival_int = req->mid; become_root(); - if (SMB_VFS_AIO_WRITE(fsp,a) == -1) { + ret = SMB_VFS_AIO_WRITE(fsp, a); + unbecome_root(); + + if (ret == -1) { DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. " "Error %s\n", strerror(errno) )); - delete_aio_ex(aio_ex); - unbecome_root(); + TALLOC_FREE(aio_ex); return False; } - unbecome_root(); - + + aio_ex->req = talloc_move(aio_ex, &req); + release_level_2_oplocks_on_change(fsp); if (!write_through && !lp_syncalways(SNUM(fsp->conn)) @@ -406,7 +368,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write " "behind for file %s\n", fsp->fsp_name )); } else { - srv_defer_sign_response(aio_ex->mid); + srv_defer_sign_response(aio_ex->req->mid); } outstanding_aio_calls++; @@ -414,7 +376,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, "%s, offset %.0f, len = %u (mid = %u) " "outstanding_aio_calls = %d\n", fsp->fsp_name, (double)startpos, (unsigned int)numtowrite, - (unsigned int)aio_ex->mid, outstanding_aio_calls )); + (unsigned int)aio_ex->req->mid, outstanding_aio_calls )); return True; } @@ -442,7 +404,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) /* If errno is ECANCELED then don't return anything to the * client. */ if (errno == ECANCELED) { - srv_cancel_sign_response(aio_ex->mid); + srv_cancel_sign_response(aio_ex->req->mid); return 0; } @@ -536,7 +498,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) /* If errno is ECANCELED then don't return anything to the * client. */ if (errno == ECANCELED) { - srv_cancel_sign_response(aio_ex->mid); + srv_cancel_sign_response(aio_ex->req->mid); return 0; } @@ -544,7 +506,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull); srv_set_message(outbuf,0,0,true); } else { - bool write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0); + bool write_through = BITSETW(aio_ex->req->vwv+7,0); NTSTATUS status; SSVAL(outbuf,smb_vwv2,nwritten); @@ -600,16 +562,11 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr) if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) { DEBUG(10,( "handle_aio_completed: operation mid %u still in " "process for file %s\n", - aio_ex->mid, aio_ex->fsp->fsp_name )); + aio_ex->req->mid, aio_ex->fsp->fsp_name )); return False; } - if (aio_ex->read_req) { - err = handle_aio_read_complete(aio_ex); - } else { - err = handle_aio_write_complete(aio_ex); - } - + err = aio_ex->handle_completion(aio_ex); if (err) { *perr = err; /* Only save non-zero errors. */ } @@ -666,7 +623,7 @@ int process_aio_queue(void) continue; } - delete_aio_ex(aio_ex); + TALLOC_FREE(aio_ex); } outstanding_aio_calls -= signals_received; @@ -738,7 +695,7 @@ int wait_for_aio_completion(files_struct *fsp) DEBUG(10,("wait_for_aio_completion: returned err = %d, " "errno = %s\n", err, strerror(errno) )); - + if (err == -1 && errno == EAGAIN) { DEBUG(0,("wait_for_aio_completion: aio_suspend timed " "out waiting for %d events after a wait of " @@ -767,7 +724,7 @@ int wait_for_aio_completion(files_struct *fsp) if (!handle_aio_completed(aio_ex, &err)) { continue; } - delete_aio_ex(aio_ex); + TALLOC_FREE(aio_ex); } SAFE_FREE(aiocb_list); diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 4374b50eac..2237a89ace 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -2,17 +2,17 @@ Unix SMB/CIFS implementation. Blocking Locking functions Copyright (C) Jeremy Allison 1998-2003 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ @@ -26,10 +26,9 @@ notify. It consists of the requesting SMB and the expiry time. *****************************************************************************/ -typedef struct _blocking_lock_record { - struct _blocking_lock_record *next; - struct _blocking_lock_record *prev; - int com_type; +typedef struct blocking_lock_record { + struct blocking_lock_record *next; + struct blocking_lock_record *prev; files_struct *fsp; struct timeval expire_time; int lock_num; @@ -39,9 +38,7 @@ typedef struct _blocking_lock_record { uint32_t blocking_pid; /* PID that blocks us. */ enum brl_flavour lock_flav; enum brl_type lock_type; - char *inbuf; - int length; - bool encrypted; + struct smb_request *req; } blocking_lock_record; /* dlink list we store pending lock records on. */ @@ -54,16 +51,6 @@ static blocking_lock_record *blocking_lock_cancelled_queue; static struct timed_event *brl_timeout; /**************************************************************************** - Destructor for the above structure. -****************************************************************************/ - -static void free_blocking_lock_record(blocking_lock_record *blr) -{ - SAFE_FREE(blr->inbuf); - SAFE_FREE(blr); -} - -/**************************************************************************** Determine if this is a secondary element of a chained SMB. **************************************************************************/ @@ -150,7 +137,7 @@ static bool recalc_brl_timeout(void) ****************************************************************************/ bool push_blocking_lock_request( struct byte_range_lock *br_lck, - const struct smb_request *req, + struct smb_request *req, files_struct *fsp, int lock_timeout, int lock_num, @@ -162,7 +149,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, uint32_t blocking_pid) { static bool set_lock_msg; - size_t length = smb_len(req->inbuf)+4; blocking_lock_record *blr; NTSTATUS status; @@ -176,7 +162,8 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, * the expiration time here. */ - if((blr = SMB_MALLOC_P(blocking_lock_record)) == NULL) { + blr = talloc(NULL, struct blocking_lock_record); + if (blr == NULL) { DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" )); return False; } @@ -184,13 +171,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, blr->next = NULL; blr->prev = NULL; - if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) { - DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" )); - SAFE_FREE(blr); - return False; - } - - blr->com_type = CVAL(req->inbuf,smb_com); blr->fsp = fsp; if (lock_timeout == -1) { blr->expire_time.tv_sec = 0; @@ -206,9 +186,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, blr->lock_type = lock_type; blr->offset = offset; blr->count = count; - memcpy(blr->inbuf, req->inbuf, length); - blr->length = length; - blr->encrypted = req->encrypted; /* Add a pending lock record for this. */ status = brl_lock(smbd_messaging_context(), br_lck, @@ -224,10 +201,12 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n")); DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); + TALLOC_FREE(blr); return False; } + blr->req = talloc_move(blr, &req); + DLIST_ADD_END(blocking_lock_queue, blr, blocking_lock_record *); recalc_brl_timeout(); @@ -238,14 +217,14 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, set_lock_msg = True; } - DEBUG(3,("push_blocking_lock_request: lock request length=%u blocked with " + DEBUG(3,("push_blocking_lock_request: lock request blocked with " "expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n", - (unsigned int)length, (unsigned int)blr->expire_time.tv_sec, + (unsigned int)blr->expire_time.tv_sec, (unsigned int)blr->expire_time.tv_usec, lock_timeout, blr->fsp->fnum, blr->fsp->fsp_name )); /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(SVAL(req->inbuf,smb_mid)); + srv_defer_sign_response(blr->req->mid); return True; } @@ -256,14 +235,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, static void reply_lockingX_success(blocking_lock_record *blr) { - struct smb_request *req; - - if (!(req = talloc(talloc_tos(), struct smb_request))) { - smb_panic("Could not allocate smb_request"); - } - - init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted); - reply_outbuf(req, 2, 0); + reply_outbuf(blr->req, 2, 0); /* * As this message is a lockingX call we must handle @@ -273,13 +245,14 @@ static void reply_lockingX_success(blocking_lock_record *blr) * that here and must set up the chain info manually. */ - chain_reply(req); + chain_reply(blr->req); - if (!srv_send_smb(smbd_server_fd(), - (char *)req->outbuf, + if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf, IS_CONN_ENCRYPTED(blr->fsp->conn))) { exit_server_cleanly("send_blocking_reply: srv_send_smb failed."); } + + TALLOC_FREE(blr->req->outbuf); } /**************************************************************************** @@ -288,11 +261,6 @@ static void reply_lockingX_success(blocking_lock_record *blr) static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status) { - char outbuf[smb_size]; - char *inbuf = blr->inbuf; - - construct_reply_common(inbuf, outbuf); - /* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to FILE_LOCK_CONFLICT! (tridge) */ if (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) { @@ -315,10 +283,12 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat } } - ERROR_NT(status); - if (!srv_send_smb(smbd_server_fd(),outbuf, blr->encrypted)) { + reply_nterror(blr->req, status); + if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf, + blr->req->encrypted)) { exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed."); } + TALLOC_FREE(blr->req->outbuf); } /**************************************************************************** @@ -328,18 +298,18 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) { - char *inbuf = blr->inbuf; files_struct *fsp = blr->fsp; - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); + uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); uint64_t count = (uint64_t)0, offset = (uint64_t) 0; uint32 lock_pid; - unsigned char locktype = CVAL(inbuf,smb_vwv3); + unsigned char locktype = CVAL(blr->req->vwv+3, 0); bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - char *data; + uint8_t *data; int i; - data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); - + data = (uint8_t *)blr->req->buf + + ((large_file_format ? 20 : 10)*num_ulocks); + /* * Data now points at the beginning of the list * of smb_lkrng structs. @@ -350,19 +320,19 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) * as under POSIX rules, if we have a lock already there, we * will delete it (and we shouldn't) ..... */ - + for(i = blr->lock_num - 1; i >= 0; i--) { bool err; - + lock_pid = get_lock_pid( data, i, large_file_format); count = get_lock_count( data, i, large_file_format); offset = get_lock_offset( data, i, large_file_format, &err); - + /* * We know err cannot be set as if it was the lock * request would never have been queued. JRA. */ - + do_unlock(smbd_messaging_context(), fsp, lock_pid, @@ -370,7 +340,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) offset, WINDOWS_LOCK); } - + generic_blocking_lock_error(blr, status); } @@ -380,28 +350,28 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status) static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status) { - switch(blr->com_type) { + switch(blr->req->cmd) { case SMBlockingX: reply_lockingX_error(blr, status); break; case SMBtrans2: case SMBtranss2: - { - char outbuf[smb_size]; - char *inbuf = blr->inbuf; - construct_reply_common(inbuf, outbuf); - /* construct_reply_common has done us the favor to pre-fill the - * command field with SMBtranss2 which is wrong :-) - */ - SCVAL(outbuf,smb_com,SMBtrans2); - ERROR_NT(status); - if (!srv_send_smb(smbd_server_fd(), - outbuf, - IS_CONN_ENCRYPTED(blr->fsp->conn))) { - exit_server_cleanly("blocking_lock_reply_error: srv_send_smb failed."); - } - break; + reply_nterror(blr->req, status); + + /* + * construct_reply_common has done us the favor to pre-fill + * the command field with SMBtranss2 which is wrong :-) + */ + SCVAL(blr->req->outbuf,smb_com,SMBtrans2); + + if (!srv_send_smb(smbd_server_fd(), + (char *)blr->req->outbuf, + IS_CONN_ENCRYPTED(blr->fsp->conn))) { + exit_server_cleanly("blocking_lock_reply_error: " + "srv_send_smb failed."); } + TALLOC_FREE(blr->req->outbuf); + break; default: DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n")); exit_server("PANIC - unknown type on blocking lock queue"); @@ -415,18 +385,18 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status static bool process_lockingX(blocking_lock_record *blr) { - char *inbuf = blr->inbuf; - unsigned char locktype = CVAL(inbuf,smb_vwv3); + unsigned char locktype = CVAL(blr->req->vwv+3, 0); files_struct *fsp = blr->fsp; - uint16 num_ulocks = SVAL(inbuf,smb_vwv6); - uint16 num_locks = SVAL(inbuf,smb_vwv7); + uint16 num_ulocks = SVAL(blr->req->vwv+6, 0); + uint16 num_locks = SVAL(blr->req->vwv+7, 0); uint64_t count = (uint64_t)0, offset = (uint64_t)0; uint32 lock_pid; bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES); - char *data; + uint8_t *data; NTSTATUS status = NT_STATUS_OK; - data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks); + data = (uint8_t *)blr->req->buf + + ((large_file_format ? 20 : 10)*num_ulocks); /* * Data now points at the beginning of the list @@ -440,7 +410,7 @@ static bool process_lockingX(blocking_lock_record *blr) lock_pid = get_lock_pid( data, blr->lock_num, large_file_format); count = get_lock_count( data, blr->lock_num, large_file_format); offset = get_lock_offset( data, blr->lock_num, large_file_format, &err); - + /* * We know err cannot be set as if it was the lock * request would never have been queued. JRA. @@ -469,20 +439,21 @@ static bool process_lockingX(blocking_lock_record *blr) /* * Success - we got all the locks. */ - + DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n", fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) ); reply_lockingX_success(blr); return True; - } else if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && - !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { - /* - * We have other than a "can't get lock" - * error. Free any locks we had and return an error. - * Return True so we get dequeued. - */ - + } + + if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) && + !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) { + /* + * We have other than a "can't get lock" + * error. Free any locks we had and return an error. + * Return True so we get dequeued. + */ blocking_lock_reply_error(blr, status); return True; } @@ -490,11 +461,11 @@ static bool process_lockingX(blocking_lock_record *blr) /* * Still can't get all the locks - keep waiting. */ - + DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \ Waiting....\n", blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum)); - + return False; } @@ -505,7 +476,6 @@ Waiting....\n", static bool process_trans2(blocking_lock_record *blr) { - struct smb_request *req; char params[2]; NTSTATUS status; struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(), @@ -535,17 +505,9 @@ static bool process_trans2(blocking_lock_record *blr) /* We finally got the lock, return success. */ - if (!(req = talloc(talloc_tos(), struct smb_request))) { - blocking_lock_reply_error(blr, NT_STATUS_NO_MEMORY); - return True; - } - - init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted); - - SCVAL(req->inbuf, smb_com, SMBtrans2); SSVAL(params,0,0); /* Fake up max_data_bytes here - we know it fits. */ - send_trans2_replies(blr->fsp->conn, req, params, 2, NULL, 0, 0xffff); + send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff); return True; } @@ -557,7 +519,7 @@ static bool process_trans2(blocking_lock_record *blr) static bool blocking_lock_record_process(blocking_lock_record *blr) { - switch(blr->com_type) { + switch(blr->req->cmd) { case SMBlockingX: return process_lockingX(blr); case SMBtrans2: @@ -579,37 +541,39 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo blocking_lock_record *blr, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { - next = blr->next; - if(blr->fsp->fnum == fsp->fnum) { - unsigned char locktype = 0; - - if (blr->com_type == SMBlockingX) { - locktype = CVAL(blr->inbuf,smb_vwv3); - } - - if (br_lck) { - DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \ -file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); + unsigned char locktype = 0; - brl_lock_cancel(br_lck, - blr->lock_pid, - procid_self(), - blr->offset, - blr->count, - blr->lock_flav); + next = blr->next; + if (blr->fsp->fnum != fsp->fnum) { + continue; + } - blocking_lock_cancel(fsp, - blr->lock_pid, - blr->offset, - blr->count, - blr->lock_flav, - locktype, - NT_STATUS_RANGE_NOT_LOCKED); - } - /* We're closing the file fsp here, so ensure - * we don't have a dangling pointer. */ - blr->fsp = NULL; + if (blr->req->cmd == SMBlockingX) { + locktype = CVAL(blr->req->vwv+3, 0); } + + DEBUG(10, ("remove_pending_lock_requests_by_fid - removing " + "request type %d for file %s fnum = %d\n", + blr->req->cmd, fsp->fsp_name, fsp->fnum)); + + brl_lock_cancel(br_lck, + blr->lock_pid, + procid_self(), + blr->offset, + blr->count, + blr->lock_flav); + + blocking_lock_cancel(fsp, + blr->lock_pid, + blr->offset, + blr->count, + blr->lock_flav, + locktype, + NT_STATUS_RANGE_NOT_LOCKED); + + /* We're closing the file fsp here, so ensure + * we don't have a dangling pointer. */ + blr->fsp = NULL; } } @@ -622,28 +586,36 @@ void remove_pending_lock_requests_by_mid(int mid) blocking_lock_record *blr, *next = NULL; for(blr = blocking_lock_queue; blr; blr = next) { + files_struct *fsp; + struct byte_range_lock *br_lck; + next = blr->next; - if(SVAL(blr->inbuf,smb_mid) == mid) { - files_struct *fsp = blr->fsp; - struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); - if (br_lck) { - DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \ -file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum )); + if (blr->req->mid != mid) { + continue; + } - brl_lock_cancel(br_lck, + fsp = blr->fsp; + br_lck = brl_get_locks(talloc_tos(), fsp); + + if (br_lck) { + DEBUG(10, ("remove_pending_lock_requests_by_mid - " + "removing request type %d for file %s fnum " + "= %d\n", blr->req->cmd, fsp->fsp_name, + fsp->fnum )); + + brl_lock_cancel(br_lck, blr->lock_pid, procid_self(), blr->offset, blr->count, blr->lock_flav); - TALLOC_FREE(br_lck); - } - - blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); - DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); + TALLOC_FREE(br_lck); } + + blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); + DLIST_REMOVE(blocking_lock_queue, blr); + TALLOC_FREE(blr); } } @@ -657,7 +629,7 @@ bool blocking_lock_was_deferred(int mid) for(blr = blocking_lock_queue; blr; blr = next) { next = blr->next; - if(SVAL(blr->inbuf,smb_mid) == mid) { + if(blr->req->mid == mid) { return True; } } @@ -693,86 +665,18 @@ static void process_blocking_lock_queue(void) */ for (blr = blocking_lock_queue; blr; blr = next) { - connection_struct *conn = NULL; - uint16 vuid; - files_struct *fsp = NULL; next = blr->next; /* - * Ensure we don't have any old chain_fsp values - * sitting around.... - */ - chain_size = 0; - fsp = blr->fsp; - - conn = conn_find(SVAL(blr->inbuf,smb_tid)); - vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : - SVAL(blr->inbuf,smb_uid); - - DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n", - fsp->fnum, fsp->fsp_name )); - - if(!change_to_user(conn,vuid)) { - struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); - - /* - * Remove the entry and return an error to the client. - */ - - if (br_lck) { - brl_lock_cancel(br_lck, - blr->lock_pid, - procid_self(), - blr->offset, - blr->count, - blr->lock_flav); - TALLOC_FREE(br_lck); - } - - DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n", - vuid )); - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); - recalc_timeout = True; - continue; - } - - if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) { - struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); - - /* - * Remove the entry and return an error to the client. - */ - - if (br_lck) { - brl_lock_cancel(br_lck, - blr->lock_pid, - procid_self(), - blr->offset, - blr->count, - blr->lock_flav); - TALLOC_FREE(br_lck); - } - - DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) )); - blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED); - DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); - recalc_timeout = True; - change_to_root_user(); - continue; - } - - /* * Go through the remaining locks and try and obtain them. * The call returns True if all locks were obtained successfully * and False if we still need to wait. */ if(blocking_lock_record_process(blr)) { - struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); + struct byte_range_lock *br_lck = brl_get_locks( + talloc_tos(), blr->fsp); if (br_lck) { brl_lock_cancel(br_lck, @@ -785,21 +689,19 @@ static void process_blocking_lock_queue(void) } DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); + TALLOC_FREE(blr); recalc_timeout = True; - change_to_root_user(); continue; } - change_to_root_user(); - /* * We couldn't get the locks for this record on the list. * If the time has expired, return a lock error. */ if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) { - struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp); + struct byte_range_lock *br_lck = brl_get_locks( + talloc_tos(), blr->fsp); /* * Lock expired - throw away all previously @@ -807,8 +709,10 @@ static void process_blocking_lock_queue(void) */ if (br_lck) { - DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n", - fsp->fnum, fsp->fsp_name )); + DEBUG(5,("process_blocking_lock_queue: " + "pending lock fnum = %d for file %s " + "timed out.\n", blr->fsp->fnum, + blr->fsp->fsp_name )); brl_lock_cancel(br_lck, blr->lock_pid, @@ -821,7 +725,7 @@ static void process_blocking_lock_queue(void) blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT); DLIST_REMOVE(blocking_lock_queue, blr); - free_blocking_lock_record(blr); + TALLOC_FREE(blr); recalc_timeout = True; } } @@ -865,7 +769,7 @@ static void process_blocking_lock_cancel_message(struct messaging_context *ctx, blocking_lock_reply_error(blr, err); DLIST_REMOVE(blocking_lock_cancelled_queue, blr); - free_blocking_lock_record(blr); + TALLOC_FREE(blr); } /**************************************************************************** @@ -908,9 +812,9 @@ bool blocking_lock_cancel(files_struct *fsp, } /* Check the flags are right. */ - if (blr->com_type == SMBlockingX && + if (blr->req->cmd == SMBlockingX && (locktype & LOCKING_ANDX_LARGE_FILES) != - (CVAL(blr->inbuf,smb_vwv3) & LOCKING_ANDX_LARGE_FILES)) { + (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) { return False; } diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 64a4311256..e6d2bbf59f 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -184,17 +184,17 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass, /* Make slave stdin/out/err of child. */ - if (sys_dup2(slave, STDIN_FILENO) != STDIN_FILENO) + if (dup2(slave, STDIN_FILENO) != STDIN_FILENO) { DEBUG(3, ("Could not re-direct stdin\n")); return (False); } - if (sys_dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) + if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO) { DEBUG(3, ("Could not re-direct stdout\n")); return (False); } - if (sys_dup2(slave, STDERR_FILENO) != STDERR_FILENO) + if (dup2(slave, STDERR_FILENO) != STDERR_FILENO) { DEBUG(3, ("Could not re-direct stderr\n")); return (False); diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index 0ce226809e..26a4212ec9 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -81,7 +81,8 @@ static void copy_trans_params_and_data(char *outbuf, int align, Send a trans reply. ****************************************************************************/ -void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, +void send_trans_reply(connection_struct *conn, + struct smb_request *req, char *rparam, int rparam_len, char *rdata, int rdata_len, bool buffer_too_large) @@ -90,7 +91,6 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, int tot_data_sent = 0; int tot_param_sent = 0; int align; - char *outbuf; int ldata = rdata ? rdata_len : 0; int lparam = rparam ? rparam_len : 0; @@ -103,38 +103,43 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, align = ((this_lparam)%4); - if (!create_outbuf(talloc_tos(), (char *)inbuf, &outbuf, - 10, 1+align+this_ldata+this_lparam)) { - smb_panic("could not allocate outbuf"); - } + reply_outbuf(req, 10, 1+align+this_ldata+this_lparam); + + /* + * We might have SMBtranss in req which was transferred to the outbuf, + * fix that. + */ + SCVAL(req->outbuf, smb_com, SMBtrans); - copy_trans_params_and_data(outbuf, align, + copy_trans_params_and_data((char *)req->outbuf, align, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); - SSVAL(outbuf,smb_vwv0,lparam); - SSVAL(outbuf,smb_vwv1,ldata); - SSVAL(outbuf,smb_vwv3,this_lparam); - SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); - SSVAL(outbuf,smb_vwv5,0); - SSVAL(outbuf,smb_vwv6,this_ldata); - SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align, - outbuf)); - SSVAL(outbuf,smb_vwv8,0); - SSVAL(outbuf,smb_vwv9,0); + SSVAL(req->outbuf,smb_vwv0,lparam); + SSVAL(req->outbuf,smb_vwv1,ldata); + SSVAL(req->outbuf,smb_vwv3,this_lparam); + SSVAL(req->outbuf,smb_vwv4, + smb_offset(smb_buf(req->outbuf)+1, req->outbuf)); + SSVAL(req->outbuf,smb_vwv5,0); + SSVAL(req->outbuf,smb_vwv6,this_ldata); + SSVAL(req->outbuf,smb_vwv7, + smb_offset(smb_buf(req->outbuf)+1+this_lparam+align, + req->outbuf)); + SSVAL(req->outbuf,smb_vwv8,0); + SSVAL(req->outbuf,smb_vwv9,0); if (buffer_too_large) { - error_packet_set((char *)outbuf, ERRDOS, ERRmoredata, + error_packet_set((char *)req->outbuf, ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__); } - show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(), (char *)outbuf, + show_msg((char *)req->outbuf); + if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, IS_CONN_ENCRYPTED(conn))) { exit_server_cleanly("send_trans_reply: srv_send_smb failed."); } - TALLOC_FREE(outbuf); + TALLOC_FREE(req->outbuf); tot_data_sent = this_ldata; tot_param_sent = this_lparam; @@ -154,39 +159,45 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf, align = (this_lparam%4); - if (!create_outbuf(talloc_tos(), (char *)inbuf, &outbuf, - 10, 1+align+this_ldata+this_lparam)) { - smb_panic("could not allocate outbuf"); - } + reply_outbuf(req, 10, 1+align+this_ldata+this_lparam); + + /* + * We might have SMBtranss in req which was transferred to the + * outbuf, fix that. + */ + SCVAL(req->outbuf, smb_com, SMBtrans); - copy_trans_params_and_data(outbuf, align, + copy_trans_params_and_data((char *)req->outbuf, align, rparam, tot_param_sent, this_lparam, rdata, tot_data_sent, this_ldata); - SSVAL(outbuf,smb_vwv3,this_lparam); - SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf)); - SSVAL(outbuf,smb_vwv5,tot_param_sent); - SSVAL(outbuf,smb_vwv6,this_ldata); - SSVAL(outbuf,smb_vwv7, - smb_offset(smb_buf(outbuf)+1+this_lparam+align, outbuf)); - SSVAL(outbuf,smb_vwv8,tot_data_sent); - SSVAL(outbuf,smb_vwv9,0); + SSVAL(req->outbuf,smb_vwv3,this_lparam); + SSVAL(req->outbuf,smb_vwv4, + smb_offset(smb_buf(req->outbuf)+1,req->outbuf)); + SSVAL(req->outbuf,smb_vwv5,tot_param_sent); + SSVAL(req->outbuf,smb_vwv6,this_ldata); + SSVAL(req->outbuf,smb_vwv7, + smb_offset(smb_buf(req->outbuf)+1+this_lparam+align, + req->outbuf)); + SSVAL(req->outbuf,smb_vwv8,tot_data_sent); + SSVAL(req->outbuf,smb_vwv9,0); if (buffer_too_large) { - error_packet_set(outbuf, ERRDOS, ERRmoredata, + error_packet_set((char *)req->outbuf, + ERRDOS, ERRmoredata, STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__); } - show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(), outbuf, + show_msg((char *)req->outbuf); + if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, IS_CONN_ENCRYPTED(conn))) exit_server_cleanly("send_trans_reply: srv_send_smb " "failed."); tot_data_sent += this_ldata; tot_param_sent += this_lparam; - TALLOC_FREE(outbuf); + TALLOC_FREE(req->outbuf); } } @@ -218,7 +229,7 @@ static void api_rpc_trans_reply(connection_struct *conn, return; } - send_trans_reply(conn, req->inbuf, NULL, 0, (char *)rdata, data_len, + send_trans_reply(conn, req, NULL, 0, (char *)rdata, data_len, is_data_outstanding); SAFE_FREE(rdata); return; @@ -239,7 +250,7 @@ static void api_WNPHS(connection_struct *conn, struct smb_request *req, DEBUG(4,("WaitNamedPipeHandleState priority %x\n", (int)SVAL(param,0))); - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); + send_trans_reply(conn, req, NULL, 0, NULL, 0, False); } @@ -257,7 +268,7 @@ static void api_SNPHS(connection_struct *conn, struct smb_request *req, DEBUG(4,("SetNamedPipeHandleState to code %x\n", (int)SVAL(param,0))); - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False); + send_trans_reply(conn, req, NULL, 0, NULL, 0, False); } @@ -276,7 +287,7 @@ static void api_no_reply(connection_struct *conn, struct smb_request *req) DEBUG(3,("Unsupported API fd command\n")); /* now send the reply */ - send_trans_reply(conn, req->inbuf, rparam, 4, NULL, 0, False); + send_trans_reply(conn, req, rparam, 4, NULL, 0, False); return; } @@ -320,8 +331,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid, /* Win9x does this call with a unicode pipe name, not a pnum. */ /* Just return success for now... */ DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n")); - send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, - False); + send_trans_reply(conn, req, NULL, 0, NULL, 0, False); return; } @@ -506,10 +516,10 @@ void reply_trans(struct smb_request *req) size = smb_len(req->inbuf) + 4; av_size = smb_len(req->inbuf); - dsoff = SVAL(req->inbuf, smb_dsoff); - dscnt = SVAL(req->inbuf, smb_dscnt); - psoff = SVAL(req->inbuf, smb_psoff); - pscnt = SVAL(req->inbuf, smb_pscnt); + dsoff = SVAL(req->vwv+12, 0); + dscnt = SVAL(req->vwv+11, 0); + psoff = SVAL(req->vwv+10, 0); + pscnt = SVAL(req->vwv+9, 0); result = allow_new_trans(conn->pending_trans, req->mid); if (!NT_STATUS_IS_OK(result)) { @@ -531,20 +541,20 @@ void reply_trans(struct smb_request *req) state->mid = req->mid; state->vuid = req->vuid; - state->setup_count = CVAL(req->inbuf, smb_suwcnt); + state->setup_count = CVAL(req->vwv+13, 0); state->setup = NULL; - state->total_param = SVAL(req->inbuf, smb_tpscnt); + state->total_param = SVAL(req->vwv+0, 0); state->param = NULL; - state->total_data = SVAL(req->inbuf, smb_tdscnt); + state->total_data = SVAL(req->vwv+1, 0); state->data = NULL; - state->max_param_return = SVAL(req->inbuf, smb_mprcnt); - state->max_data_return = SVAL(req->inbuf, smb_mdrcnt); - state->max_setup_return = CVAL(req->inbuf, smb_msrcnt); - state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0); - state->one_way = BITSETW(req->inbuf+smb_vwv5,1); + state->max_param_return = SVAL(req->vwv+2, 0); + state->max_data_return = SVAL(req->vwv+3, 0); + state->max_setup_return = CVAL(req->vwv+4, 0); + state->close_on_completion = BITSETW(req->vwv+5, 0); + state->one_way = BITSETW(req->vwv+5, 1); - srvstr_pull_buf_talloc(state, req->inbuf, req->flags2, &state->name, - smb_buf(req->inbuf), STR_TERMINATE); + srvstr_pull_req_talloc(state, req, &state->name, req->buf, + STR_TERMINATE); if ((dscnt > state->total_data) || (pscnt > state->total_param) || !state->name) @@ -710,20 +720,20 @@ void reply_transs(struct smb_request *req) /* Revise total_params and total_data in case they have changed * downwards */ - if (SVAL(req->inbuf, smb_vwv0) < state->total_param) - state->total_param = SVAL(req->inbuf,smb_vwv0); - if (SVAL(req->inbuf, smb_vwv1) < state->total_data) - state->total_data = SVAL(req->inbuf,smb_vwv1); + if (SVAL(req->vwv+0, 0) < state->total_param) + state->total_param = SVAL(req->vwv+0, 0); + if (SVAL(req->vwv+1, 0) < state->total_data) + state->total_data = SVAL(req->vwv+1, 0); av_size = smb_len(req->inbuf); - pcnt = SVAL(req->inbuf, smb_spscnt); - poff = SVAL(req->inbuf, smb_spsoff); - pdisp = SVAL(req->inbuf, smb_spsdisp); + pcnt = SVAL(req->vwv+2, 0); + poff = SVAL(req->vwv+3, 0); + pdisp = SVAL(req->vwv+4, 0); - dcnt = SVAL(req->inbuf, smb_sdscnt); - doff = SVAL(req->inbuf, smb_sdsoff); - ddisp = SVAL(req->inbuf, smb_sdsdisp); + dcnt = SVAL(req->vwv+5, 0); + doff = SVAL(req->vwv+6, 0); + ddisp = SVAL(req->vwv+7, 0); state->received_param += pcnt; state->received_data += dcnt; @@ -776,12 +786,6 @@ void reply_transs(struct smb_request *req) return; } - /* - * construct_reply_common will copy smb_com from inbuf to - * outbuf. SMBtranss is wrong here. - */ - SCVAL(req->inbuf,smb_com,SMBtrans); - handle_trans(conn, req, state); DLIST_REMOVE(conn->pending_trans, state); diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 0c866da706..6ed3ce2c87 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -4632,7 +4632,7 @@ void api_reply(connection_struct *conn, uint16 vuid, /* If api_Unsupported returns false we can't return anything. */ if (reply) { - send_trans_reply(conn, req->inbuf, rparam, rparam_len, + send_trans_reply(conn, req, rparam, rparam_len, rdata, rdata_len, False); } diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c index 360692c546..4d4d0dc5af 100644 --- a/source3/smbd/mangle.c +++ b/source3/smbd/mangle.c @@ -140,7 +140,7 @@ bool name_to_8_3(const char *in, /* name mangling can be disabled for speed, in which case we just truncate the string */ if (!lp_manglednames(p)) { - safe_strcpy(out,in,12); + strlcpy(out, in, 13); return True; } diff --git a/source3/smbd/map_username.c b/source3/smbd/map_username.c index a8899dd538..f549f0c9f3 100644 --- a/source3/smbd/map_username.c +++ b/source3/smbd/map_username.c @@ -178,7 +178,7 @@ bool map_username(fstring user) /* skip lines like 'user = ' */ - dosuserlist = str_list_make(talloc_tos(), dosname, NULL); + dosuserlist = str_list_make_v3(talloc_tos(), dosname, NULL); if (!dosuserlist) { DEBUG(0,("Bad username map entry. Unable to build user list. Ignoring.\n")); continue; diff --git a/source3/smbd/message.c b/source3/smbd/message.c index 62df5c37eb..65eaeca777 100644 --- a/source3/smbd/message.c +++ b/source3/smbd/message.c @@ -140,8 +140,8 @@ void reply_sends(struct smb_request *req) { struct msg_state *state; int len; - char *msg; - char *p; + const char *msg; + const char *p; START_PROFILE(SMBsends); @@ -153,18 +153,16 @@ void reply_sends(struct smb_request *req) state = talloc(talloc_tos(), struct msg_state); - p = smb_buf(req->inbuf)+1; - p += srvstr_pull_buf_talloc( - state, (char *)req->inbuf, req->flags2, &state->from, p, - STR_ASCII|STR_TERMINATE) + 1; - p += srvstr_pull_buf_talloc( - state, (char *)req->inbuf, req->flags2, &state->to, p, - STR_ASCII|STR_TERMINATE) + 1; + p = (const char *)req->buf + 1; + p += srvstr_pull_req_talloc( + state, req, &state->from, p, STR_ASCII|STR_TERMINATE) + 1; + p += srvstr_pull_req_talloc( + state, req, &state->to, p, STR_ASCII|STR_TERMINATE) + 1; msg = p; len = SVAL(msg,0); - len = MIN(len, smb_bufrem(req->inbuf, msg+2)); + len = MIN(len, smbreq_bufrem(req, msg+2)); state->msg = talloc_array(state, char, len); @@ -191,7 +189,7 @@ void reply_sends(struct smb_request *req) void reply_sendstrt(struct smb_request *req) { - char *p; + const char *p; START_PROFILE(SMBsendstrt); @@ -211,13 +209,13 @@ void reply_sendstrt(struct smb_request *req) return; } - p = smb_buf(req->inbuf)+1; - p += srvstr_pull_buf_talloc( - smbd_msg_state, (char *)req->inbuf, req->flags2, - &smbd_msg_state->from, p, STR_ASCII|STR_TERMINATE) + 1; - p += srvstr_pull_buf_talloc( - smbd_msg_state, (char *)req->inbuf, req->flags2, - &smbd_msg_state->to, p, STR_ASCII|STR_TERMINATE) + 1; + p = (const char *)req->buf+1; + p += srvstr_pull_req_talloc( + smbd_msg_state, req, &smbd_msg_state->from, p, + STR_ASCII|STR_TERMINATE) + 1; + p += srvstr_pull_req_talloc( + smbd_msg_state, req, &smbd_msg_state->to, p, + STR_ASCII|STR_TERMINATE) + 1; DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", smbd_msg_state->from, smbd_msg_state->to ) ); @@ -236,7 +234,7 @@ void reply_sendstrt(struct smb_request *req) void reply_sendtxt(struct smb_request *req) { int len; - char *msg; + const char *msg; char *tmp; size_t old_len; @@ -254,11 +252,11 @@ void reply_sendtxt(struct smb_request *req) return; } - msg = smb_buf(req->inbuf) + 1; + msg = (const char *)req->buf + 1; old_len = talloc_get_size(smbd_msg_state->msg); - len = MIN(SVAL(msg, 0), smb_bufrem(req->inbuf, msg+2)); + len = MIN(SVAL(msg, 0), smbreq_bufrem(req, msg+2)); tmp = TALLOC_REALLOC_ARRAY(smbd_msg_state, smbd_msg_state->msg, char, old_len + len); diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index 84f111fb02..43fdc1d608 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -507,11 +507,9 @@ static const struct { void reply_negprot(struct smb_request *req) { - size_t size = smb_len(req->inbuf) + 4; int choice= -1; int protocol; - char *p; - int bcc = SVAL(smb_buf(req->inbuf),-2); + const char *p; int arch = ARCH_ALL; int num_cliprotos; char **cliprotos; @@ -528,19 +526,26 @@ void reply_negprot(struct smb_request *req) } done_negprot = True; - if (req->inbuf[size-1] != '\0') { + if (req->buflen == 0) { + DEBUG(0, ("negprot got no protocols\n")); + reply_nterror(req, NT_STATUS_INVALID_PARAMETER); + END_PROFILE(SMBnegprot); + return; + } + + if (req->buf[req->buflen-1] != '\0') { DEBUG(0, ("negprot protocols not 0-terminated\n")); reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBnegprot); return; } - p = smb_buf(req->inbuf) + 1; + p = (const char *)req->buf + 1; num_cliprotos = 0; cliprotos = NULL; - while (p < (smb_buf(req->inbuf) + bcc)) { + while (smbreq_bufrem(req, p) > 0) { char **tmp; diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 139dfe7d5b..5a517654bf 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -24,7 +24,7 @@ struct notify_change_request { struct notify_change_request *prev, *next; struct files_struct *fsp; /* backpointer for cancel by mid */ - uint8 request_buf[smb_size]; + struct smb_request *req; uint32 filter; uint32 max_param; struct notify_mid_map *mid_map; @@ -133,40 +133,33 @@ static bool notify_marshall_changes(int num_changes, *****************************************************************************/ static void change_notify_reply_packet(connection_struct *conn, - const uint8 *request_buf, + struct smb_request *req, NTSTATUS error_code) { - char outbuf[smb_size+38]; + reply_outbuf(req, 18, 0); - memset(outbuf, '\0', sizeof(outbuf)); - construct_reply_common((char *)request_buf, outbuf); - - ERROR_NT(error_code); - - /* - * Seems NT needs a transact command with an error code - * in it. This is a longer packet than a simple error. - */ - srv_set_message(outbuf,18,0,False); + if (!NT_STATUS_IS_OK(error_code)) { + error_packet_set((char *)req->outbuf, 0, 0, error_code, + __LINE__,__FILE__); + } - show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(), - outbuf, - IS_CONN_ENCRYPTED(conn))) + show_msg((char *)req->outbuf); + if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + req->encrypted)) { exit_server_cleanly("change_notify_reply_packet: srv_send_smb " "failed."); + } + TALLOC_FREE(req->outbuf); } void change_notify_reply(connection_struct *conn, - const uint8 *request_buf, uint32 max_param, + struct smb_request *req, uint32 max_param, struct notify_change_buf *notify_buf) { prs_struct ps; - struct smb_request *req = NULL; - uint8 tmp_request[smb_size]; if (notify_buf->num_changes == -1) { - change_notify_reply_packet(conn, request_buf, NT_STATUS_OK); + change_notify_reply_packet(conn, req, NT_STATUS_OK); notify_buf->num_changes = 0; return; } @@ -179,31 +172,14 @@ void change_notify_reply(connection_struct *conn, * We exceed what the client is willing to accept. Send * nothing. */ - change_notify_reply_packet(conn, request_buf, NT_STATUS_OK); - goto done; - } - - if (!(req = talloc(talloc_tos(), struct smb_request))) { - change_notify_reply_packet(conn, request_buf, NT_STATUS_NO_MEMORY); + change_notify_reply_packet(conn, req, NT_STATUS_OK); goto done; } - memcpy(tmp_request, request_buf, smb_size); - - /* - * We're only interested in the header fields here - */ - - smb_setlen((char *)tmp_request, smb_size); - SCVAL(tmp_request, smb_wct, 0); - - init_smb_request(req, tmp_request,0, conn->encrypted_tid); - send_nt_replies(conn, req, NT_STATUS_OK, prs_data_p(&ps), prs_offset(&ps), NULL, 0); done: - TALLOC_FREE(req); prs_mem_free(&ps); TALLOC_FREE(notify_buf->changes); @@ -251,7 +227,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter, return status; } -NTSTATUS change_notify_add_request(const struct smb_request *req, +NTSTATUS change_notify_add_request(struct smb_request *req, uint32 max_param, uint32 filter, bool recursive, struct files_struct *fsp) @@ -262,16 +238,16 @@ NTSTATUS change_notify_add_request(const struct smb_request *req, DEBUG(10, ("change_notify_add_request: Adding request for %s: " "max_param = %d\n", fsp->fsp_name, (int)max_param)); - if (!(request = SMB_MALLOC_P(struct notify_change_request)) - || !(map = SMB_MALLOC_P(struct notify_mid_map))) { - SAFE_FREE(request); + if (!(request = talloc(NULL, struct notify_change_request)) + || !(map = talloc(request, struct notify_mid_map))) { + TALLOC_FREE(request); return NT_STATUS_NO_MEMORY; } request->mid_map = map; map->req = request; - memcpy(request->request_buf, req->inbuf, sizeof(request->request_buf)); + request->req = talloc_move(request, &req); request->max_param = max_param; request->filter = filter; request->fsp = fsp; @@ -280,11 +256,11 @@ NTSTATUS change_notify_add_request(const struct smb_request *req, DLIST_ADD_END(fsp->notify->requests, request, struct notify_change_request *); - map->mid = SVAL(req->inbuf, smb_mid); + map->mid = request->req->mid; DLIST_ADD(notify_changes_by_mid, map); /* Push the MID of this packet on the signing queue. */ - srv_defer_sign_response(SVAL(req->inbuf,smb_mid)); + srv_defer_sign_response(request->req->mid); return NT_STATUS_OK; } @@ -314,9 +290,7 @@ static void change_notify_remove_request(struct notify_change_request *remove_re DLIST_REMOVE(fsp->notify->requests, req); DLIST_REMOVE(notify_changes_by_mid, req->mid_map); - SAFE_FREE(req->mid_map); - TALLOC_FREE(req->backend_data); - SAFE_FREE(req); + TALLOC_FREE(req); } /**************************************************************************** @@ -337,8 +311,8 @@ void remove_pending_change_notify_requests_by_mid(uint16 mid) return; } - change_notify_reply_packet(map->req->fsp->conn, - map->req->request_buf, NT_STATUS_CANCELLED); + change_notify_reply_packet(map->req->fsp->conn, map->req->req, + NT_STATUS_CANCELLED); change_notify_remove_request(map->req); } @@ -354,8 +328,8 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp, } while (fsp->notify->requests != NULL) { - change_notify_reply_packet(fsp->conn, - fsp->notify->requests->request_buf, status); + change_notify_reply_packet( + fsp->conn, fsp->notify->requests->req, status); change_notify_remove_request(fsp->notify->requests); } } @@ -449,7 +423,7 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name) */ change_notify_reply(fsp->conn, - fsp->notify->requests->request_buf, + fsp->notify->requests->req, fsp->notify->requests->max_param, fsp->notify); diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 30841686fb..1a13d962f0 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -120,6 +120,11 @@ void send_nt_replies(connection_struct *conn, + 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. */ @@ -304,11 +309,10 @@ static void do_ntcreate_pipe_open(connection_struct *conn, char *fname = NULL; int pnum = -1; char *p = NULL; - uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags); + uint32 flags = IVAL(req->vwv+3, 1); TALLOC_CTX *ctx = talloc_tos(); - srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname, - smb_buf(req->inbuf), STR_TERMINATE); + srvstr_pull_req_talloc(ctx, req, &fname, req->buf, STR_TERMINATE); if (!fname) { reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, @@ -408,24 +412,21 @@ void reply_ntcreate_and_X(struct smb_request *req) return; } - flags = IVAL(req->inbuf,smb_ntcreate_Flags); - access_mask = IVAL(req->inbuf,smb_ntcreate_DesiredAccess); - file_attributes = IVAL(req->inbuf,smb_ntcreate_FileAttributes); - share_access = IVAL(req->inbuf,smb_ntcreate_ShareAccess); - create_disposition = IVAL(req->inbuf,smb_ntcreate_CreateDisposition); - create_options = IVAL(req->inbuf,smb_ntcreate_CreateOptions); - root_dir_fid = (uint16)IVAL(req->inbuf,smb_ntcreate_RootDirectoryFid); + flags = IVAL(req->vwv+3, 1); + access_mask = IVAL(req->vwv+7, 1); + file_attributes = IVAL(req->vwv+13, 1); + share_access = IVAL(req->vwv+15, 1); + create_disposition = IVAL(req->vwv+17, 1); + create_options = IVAL(req->vwv+19, 1); + root_dir_fid = (uint16)IVAL(req->vwv+5, 1); - allocation_size = (uint64_t)IVAL(req->inbuf, - smb_ntcreate_AllocationSize); + allocation_size = (uint64_t)IVAL(req->vwv+9, 1); #ifdef LARGE_SMB_OFF_T - allocation_size |= (((uint64_t)IVAL( - req->inbuf, - smb_ntcreate_AllocationSize + 4)) << 32); + allocation_size |= (((uint64_t)IVAL(req->vwv+11, 1)) << 32); #endif - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, - smb_buf(req->inbuf), 0, STR_TERMINATE, &status); + srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); @@ -729,6 +730,9 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len, if (psd->sacl==0) { security_info_sent &= ~SACL_SECURITY_INFORMATION; } + if (security_info_sent & DACL_SECURITY_INFORMATION) { + psd->type |= SEC_DESC_DACL_PRESENT; + } if (psd->dacl==0) { security_info_sent &= ~DACL_SECURITY_INFORMATION; } @@ -1228,7 +1232,7 @@ void reply_ntrename(struct smb_request *req) connection_struct *conn = req->conn; char *oldname = NULL; char *newname = NULL; - char *p; + const char *p; NTSTATUS status; bool src_has_wcard = False; bool dest_has_wcard = False; @@ -1244,13 +1248,12 @@ void reply_ntrename(struct smb_request *req) return; } - attrs = SVAL(req->inbuf,smb_vwv0); - rename_type = SVAL(req->inbuf,smb_vwv1); + attrs = SVAL(req->vwv+0, 0); + rename_type = SVAL(req->vwv+1, 0); - p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p, - 0, STR_TERMINATE, &status, - &src_has_wcard); + p = (const char *)req->buf + 1; + p += srvstr_get_path_req_wcard(ctx, req, &oldname, p, STR_TERMINATE, + &status, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBntrename); @@ -1271,9 +1274,8 @@ void reply_ntrename(struct smb_request *req) } p++; - p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, - 0, STR_TERMINATE, &status, - &dest_has_wcard); + p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE, + &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBntrename); @@ -1446,7 +1448,8 @@ static void call_nt_transact_notify_change(connection_struct *conn, * here. */ - change_notify_reply(fsp->conn, req->inbuf, max_param_count, fsp->notify); + change_notify_reply(fsp->conn, req, max_param_count, + fsp->notify); /* * change_notify_reply() above has independently sent its @@ -2538,11 +2541,11 @@ void reply_nttrans(struct smb_request *req) size = smb_len(req->inbuf) + 4; av_size = smb_len(req->inbuf); - pscnt = IVAL(req->inbuf,smb_nt_ParameterCount); - psoff = IVAL(req->inbuf,smb_nt_ParameterOffset); - dscnt = IVAL(req->inbuf,smb_nt_DataCount); - dsoff = IVAL(req->inbuf,smb_nt_DataOffset); - function_code = SVAL(req->inbuf, smb_nt_Function); + pscnt = IVAL(req->vwv+9, 1); + psoff = IVAL(req->vwv+11, 1); + dscnt = IVAL(req->vwv+13, 1); + dsoff = IVAL(req->vwv+15, 1); + function_code = SVAL(req->vwv+18, 0); if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) { reply_doserror(req, ERRSRV, ERRaccess); @@ -2568,15 +2571,15 @@ void reply_nttrans(struct smb_request *req) state->mid = req->mid; state->vuid = req->vuid; - state->total_data = IVAL(req->inbuf, smb_nt_TotalDataCount); + state->total_data = IVAL(req->vwv+3, 1); state->data = NULL; - state->total_param = IVAL(req->inbuf, smb_nt_TotalParameterCount); + state->total_param = IVAL(req->vwv+1, 1); state->param = NULL; - state->max_data_return = IVAL(req->inbuf,smb_nt_MaxDataCount); - state->max_param_return = IVAL(req->inbuf,smb_nt_MaxParameterCount); + state->max_data_return = IVAL(req->vwv+7, 1); + state->max_param_return = IVAL(req->vwv+5, 1); /* setup count is in *words* */ - state->setup_count = 2*CVAL(req->inbuf,smb_nt_SetupCount); + state->setup_count = 2*CVAL(req->vwv+17, 1); state->setup = NULL; state->call = function_code; @@ -2691,8 +2694,7 @@ void reply_nttrans(struct smb_request *req) goto bad_param; } - memcpy( state->setup, &req->inbuf[smb_nt_SetupStart], - state->setup_count); + memcpy(state->setup, req->vwv+19, state->setup_count); dump_data(10, (uint8 *)state->setup, state->setup_count); } @@ -2763,25 +2765,23 @@ void reply_nttranss(struct smb_request *req) /* Revise state->total_param and state->total_data in case they have changed downwards */ - if (IVAL(req->inbuf, smb_nts_TotalParameterCount) - < state->total_param) { - state->total_param = IVAL(req->inbuf, - smb_nts_TotalParameterCount); + if (IVAL(req->vwv+1, 1) < state->total_param) { + state->total_param = IVAL(req->vwv+1, 1); } - if (IVAL(req->inbuf, smb_nts_TotalDataCount) < state->total_data) { - state->total_data = IVAL(req->inbuf, smb_nts_TotalDataCount); + if (IVAL(req->vwv+3, 1) < state->total_data) { + state->total_data = IVAL(req->vwv+3, 1); } size = smb_len(req->inbuf) + 4; av_size = smb_len(req->inbuf); - pcnt = IVAL(req->inbuf,smb_nts_ParameterCount); - poff = IVAL(req->inbuf, smb_nts_ParameterOffset); - pdisp = IVAL(req->inbuf, smb_nts_ParameterDisplacement); + pcnt = IVAL(req->vwv+5, 1); + poff = IVAL(req->vwv+7, 1); + pdisp = IVAL(req->vwv+9, 1); - dcnt = IVAL(req->inbuf, smb_nts_DataCount); - ddisp = IVAL(req->inbuf, smb_nts_DataDisplacement); - doff = IVAL(req->inbuf, smb_nts_DataOffset); + dcnt = IVAL(req->vwv+11, 1); + doff = IVAL(req->vwv+13, 1); + ddisp = IVAL(req->vwv+15, 1); state->received_param += pcnt; state->received_data += dcnt; @@ -2834,12 +2834,6 @@ void reply_nttranss(struct smb_request *req) return; } - /* - * construct_reply_common will copy smb_com from inbuf to - * outbuf. SMBnttranss is wrong here. - */ - SCVAL(req->inbuf,smb_com,SMBnttrans); - handle_nttrans(conn, state, req); DLIST_REMOVE(conn->pending_trans, state); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index 1564525005..3fd0d1a03a 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -30,6 +30,56 @@ struct deferred_open_record { }; /**************************************************************************** + SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES. +****************************************************************************/ + +NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd, + const NT_USER_TOKEN *token, + uint32_t access_desired, + uint32_t *access_granted) +{ + return se_access_check(sd, + token, + (access_desired & ~FILE_READ_ATTRIBUTES), + access_granted); +} + +/**************************************************************************** + Check if we have open rights. +****************************************************************************/ + +static NTSTATUS check_open_rights(struct connection_struct *conn, + const char *fname, + uint32_t access_mask) +{ + /* Check if we have rights to open. */ + NTSTATUS status; + uint32_t access_granted = 0; + struct security_descriptor *sd; + + status = SMB_VFS_GET_NT_ACL(conn, fname, + (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION),&sd); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("check_open_rights: Could not get acl " + "on %s: %s\n", + fname, + nt_errstr(status))); + return status; + } + + status = smb1_file_se_access_check(sd, + conn->server_info->ptok, + access_mask, + &access_granted); + + TALLOC_FREE(sd); + return status; +} + +/**************************************************************************** fd support routines - attempt to do a dos_open. ****************************************************************************/ @@ -337,6 +387,17 @@ static NTSTATUS open_file(files_struct *fsp, } else { fsp->fh->fd = -1; /* What we used to call a stat open. */ + if (file_existed) { + status = check_open_rights(conn, + path, + access_mask); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_file: Access denied on " + "file %s\n", + path)); + return status; + } + } } if (!file_existed) { @@ -1126,6 +1187,68 @@ static void schedule_defer_open(struct share_mode_lock *lck, } /**************************************************************************** + Work out what access_mask to use from what the client sent us. +****************************************************************************/ + +static NTSTATUS calculate_access_mask(connection_struct *conn, + const char *fname, + bool file_existed, + uint32_t access_mask, + uint32_t *access_mask_out) +{ + NTSTATUS status; + + /* + * Convert GENERIC bits to specific bits. + */ + + se_map_generic(&access_mask, &file_generic_mapping); + + /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */ + if (access_mask & MAXIMUM_ALLOWED_ACCESS) { + if (file_existed) { + + struct security_descriptor *sd; + uint32_t access_granted = 0; + + status = SMB_VFS_GET_NT_ACL(conn, fname, + (OWNER_SECURITY_INFORMATION | + GROUP_SECURITY_INFORMATION | + DACL_SECURITY_INFORMATION),&sd); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("calculate_access_mask: Could not get acl " + "on file %s: %s\n", + fname, + nt_errstr(status))); + return NT_STATUS_ACCESS_DENIED; + } + + status = smb1_file_se_access_check(sd, + conn->server_info->ptok, + access_mask, + &access_granted); + + TALLOC_FREE(sd); + + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("calculate_access_mask: Access denied on " + "file %s: when calculating maximum access\n", + fname)); + return NT_STATUS_ACCESS_DENIED; + } + + access_mask = access_granted; + } else { + access_mask = FILE_GENERIC_ALL; + } + } + + *access_mask_out = access_mask; + return NT_STATUS_OK; +} + +/**************************************************************************** Open a file with a share mode. ****************************************************************************/ @@ -1206,15 +1329,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, create_disposition, create_options, unx_mode, oplock_request)); - if ((access_mask & FILE_READ_DATA)||(access_mask & FILE_WRITE_DATA)) { - DEBUG(10, ("open_file_ntcreate: adding FILE_READ_ATTRIBUTES " - "to requested access_mask 0x%x, new mask 0x%x", - access_mask, - access_mask | FILE_READ_ATTRIBUTES )); - - access_mask |= FILE_READ_ATTRIBUTES; - } - if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) { DEBUG(0, ("No smb request but not an internal only open!\n")); return NT_STATUS_INTERNAL_ERROR; @@ -1370,16 +1484,17 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, } } - /* This is a nasty hack - must fix... JRA. */ - if (access_mask == MAXIMUM_ALLOWED_ACCESS) { - open_access_mask = access_mask = FILE_GENERIC_ALL; + status = calculate_access_mask(conn, fname, file_existed, + access_mask, + &access_mask); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_file_ntcreate: calculate_access_mask " + "on file %s returned %s\n", + fname, + nt_errstr(status))); + return status; } - /* - * Convert GENERIC bits to specific bits. - */ - - se_map_generic(&access_mask, &file_generic_mapping); open_access_mask = access_mask; if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) { @@ -1819,7 +1934,10 @@ NTSTATUS open_file_ntcreate(connection_struct *conn, /* Record the options we were opened with. */ fsp->share_access = share_access; fsp->fh->private_options = create_options; - fsp->access_mask = access_mask; + /* + * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted, + */ + fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES; if (file_existed) { /* stat opens on existing files don't get oplocks. */ @@ -2135,6 +2253,17 @@ NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_NOT_A_DIRECTORY; } + status = calculate_access_mask(conn, fname, dir_existed, + access_mask, + &access_mask); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_directory: calculate_access_mask " + "on file %s returned %s\n", + fname, + nt_errstr(status))); + return status; + } + switch( create_disposition ) { case FILE_OPEN: @@ -2209,6 +2338,19 @@ NTSTATUS open_directory(connection_struct *conn, return NT_STATUS_NOT_A_DIRECTORY; } + if (info == FILE_WAS_OPENED) { + status = check_open_rights(conn, + fname, + access_mask); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(10, ("open_directory: check_open_rights on " + "file %s failed with %s\n", + fname, + nt_errstr(status))); + return status; + } + } + status = file_new(req, conn, &fsp); if(!NT_STATUS_IS_OK(status)) { return status; @@ -2228,8 +2370,10 @@ NTSTATUS open_directory(connection_struct *conn, fsp->share_access = share_access; fsp->fh->private_options = create_options; - fsp->access_mask = access_mask; - + /* + * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted, + */ + fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES; fsp->print_file = False; fsp->modified = False; fsp->oplock_type = NO_OPLOCK; @@ -2779,7 +2923,12 @@ NTSTATUS create_file_unixpath(connection_struct *conn, security_acl_map_generic(sd->dacl, &file_generic_mapping); security_acl_map_generic(sd->sacl, &file_generic_mapping); - status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd); + if (sec_info_sent & (OWNER_SECURITY_INFORMATION| + GROUP_SECURITY_INFORMATION| + DACL_SECURITY_INFORMATION| + SACL_SECURITY_INFORMATION)) { + status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd); + } fsp->access_mask = saved_access_mask; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 88e7b766be..84b40f28cc 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -576,7 +576,7 @@ static bool user_ok(const char *user, int snum) TALLOC_FREE(valid); if (ret && lp_onlyuser(snum)) { - char **user_list = str_list_make( + char **user_list = str_list_make_v3( talloc_tos(), lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index d971e9dc62..b52b1b02d0 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -48,8 +48,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) NTSTATUS status; /* XXXX we need to handle passed times, sattr and flags */ - srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &pipe_name, - smb_buf(req->inbuf), STR_TERMINATE); + srvstr_pull_req_talloc(ctx, req, &pipe_name, req->buf, STR_TERMINATE); if (!pipe_name) { reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND, ERRDOS, ERRbadpipe); @@ -119,10 +118,10 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req) void reply_pipe_write(struct smb_request *req) { - files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); - size_t numtowrite = SVAL(req->inbuf,smb_vwv1); + files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0)); + size_t numtowrite = SVAL(req->vwv+1, 0); ssize_t nwritten; - uint8_t *data; + const uint8_t *data; if (!fsp_is_np(fsp)) { reply_doserror(req, ERRDOS, ERRbadfid); @@ -134,7 +133,7 @@ void reply_pipe_write(struct smb_request *req) return; } - data = (uint8_t *)smb_buf(req->inbuf) + 3; + data = req->buf + 3; if (numtowrite == 0) { nwritten = 0; @@ -171,13 +170,12 @@ void reply_pipe_write(struct smb_request *req) void reply_pipe_write_and_X(struct smb_request *req) { - files_struct *fsp = file_fsp(req, SVAL(req->inbuf, smb_vwv2)); - size_t numtowrite = SVAL(req->inbuf,smb_vwv10); + files_struct *fsp = file_fsp(req, SVAL(req->vwv+2, 0)); + size_t numtowrite = SVAL(req->vwv+10, 0); ssize_t nwritten; - int smb_doff = SVAL(req->inbuf, smb_vwv11); + int smb_doff = SVAL(req->vwv+11, 0); bool pipe_start_message_raw = - ((SVAL(req->inbuf, smb_vwv7) - & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) + ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE)) == (PIPE_START_MESSAGE|PIPE_RAW_MODE)); uint8_t *data; @@ -247,9 +245,9 @@ void reply_pipe_write_and_X(struct smb_request *req) void reply_pipe_read_and_X(struct smb_request *req) { - files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); - int smb_maxcnt = SVAL(req->inbuf,smb_vwv5); - int smb_mincnt = SVAL(req->inbuf,smb_vwv6); + files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0)); + int smb_maxcnt = SVAL(req->vwv+5, 0); + int smb_mincnt = SVAL(req->vwv+6, 0); ssize_t nread; uint8_t *data; bool unused; @@ -259,7 +257,7 @@ void reply_pipe_read_and_X(struct smb_request *req) is deliberate, instead we always return the next lump of data on the pipe */ #if 0 - uint32 smb_offs = IVAL(req->inbuf,smb_vwv3); + uint32 smb_offs = IVAL(req->vwv+3, 0); #endif if (!fsp_is_np(fsp)) { diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index cccf3087f7..7ca2ed787b 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3511,7 +3511,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid); /* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx - * for details. JRA. + * for details and also the log trace in bug #4308. JRA. */ if ((security_info_sent & DACL_SECURITY_INFORMATION) && @@ -4301,7 +4301,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname) finfo.fh->fd = -1; finfo.fsp_name = CONST_DISCARD(char *,fname); - if (!NT_STATUS_IS_OK(posix_fget_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd))) { + if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) { DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n")); conn_free_internal( conn ); return NULL; diff --git a/source3/smbd/process.c b/source3/smbd/process.c index a8b93d8e1c..b3cd2f26c8 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -20,8 +20,6 @@ #include "includes.h" -extern int smb_echo_count; - /* * Size of data we can send to client. Set * by the client for all protocols above CORE. @@ -39,6 +37,8 @@ SIG_ATOMIC_T got_sig_term = 0; extern bool global_machine_password_needs_changing; extern int max_send; +static void construct_reply_common(const char *inbuf, char *outbuf); + /* Accessor function for smb_read_error for smbd functions. */ /**************************************************************************** @@ -371,12 +371,16 @@ void init_smb_request(struct smb_request *req, (unsigned int)req_size )); exit_server_cleanly("Invalid SMB request"); } + req->cmd = CVAL(inbuf, smb_com); req->flags2 = SVAL(inbuf, smb_flg2); req->smbpid = SVAL(inbuf, smb_pid); req->mid = SVAL(inbuf, smb_mid); req->vuid = SVAL(inbuf, smb_uid); req->tid = SVAL(inbuf, smb_tid); req->wct = CVAL(inbuf, smb_wct); + req->vwv = (uint16_t *)(inbuf+smb_vwv); + req->buflen = smb_buflen(inbuf); + req->buf = (const uint8_t *)smb_buf(inbuf); req->unread_bytes = unread_bytes; req->encrypted = encrypted; req->conn = conn_find(req->tid); @@ -390,15 +394,14 @@ void init_smb_request(struct smb_request *req, exit_server_cleanly("Invalid SMB request"); } /* Ensure bcc is correct. */ - if (((uint8 *)smb_buf(inbuf)) + smb_buflen(inbuf) > inbuf + req_size) { + if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) { DEBUG(0,("init_smb_request: invalid bcc number %u " "(wct = %u, size %u)\n", - (unsigned int)smb_buflen(inbuf), + (unsigned int)req->buflen, (unsigned int)req->wct, (unsigned int)req_size)); exit_server_cleanly("Invalid SMB request"); } - req->inbuf = inbuf; req->outbuf = NULL; } @@ -1422,6 +1425,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in if (!change_to_user(conn,session_tag)) { reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid)); + remove_deferred_open_smb_message(req->mid); return conn; } @@ -1450,8 +1454,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in /* encrypted required from now on. */ conn->encrypt_level = Required; } else if (ENCRYPTION_REQUIRED(conn)) { - uint8 com = CVAL(req->inbuf,smb_com); - if (com != SMBtrans2 && com != SMBtranss2) { + if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) { exit_server_cleanly("encryption required " "on connection"); return conn; @@ -1486,7 +1489,6 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted) { - uint8 type = CVAL(inbuf,smb_com); connection_struct *conn; struct smb_request *req; @@ -1496,8 +1498,9 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc smb_panic("could not allocate smb_request"); } init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted); + req->inbuf = (uint8_t *)talloc_move(req, &inbuf); - conn = switch_message(type, req, size); + conn = switch_message(req->cmd, req, size); if (req->unread_bytes) { /* writeX failed. drain socket. */ @@ -1589,7 +1592,7 @@ void remove_from_common_flags2(uint32 v) common_flags2 &= ~v; } -void construct_reply_common(const char *inbuf, char *outbuf) +static void construct_reply_common(const char *inbuf, char *outbuf) { srv_set_message(outbuf,0,0,false); @@ -1607,6 +1610,11 @@ void construct_reply_common(const char *inbuf, char *outbuf) SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid)); } +void construct_reply_common_req(struct smb_request *req, char *outbuf) +{ + construct_reply_common((char *)req->inbuf, outbuf); +} + /**************************************************************************** Construct a chained reply and add it to the already made reply ****************************************************************************/ @@ -1717,6 +1725,7 @@ void chain_reply(struct smb_request *req) smb_panic("could not allocate smb_request"); } init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted); + req2->inbuf = (uint8_t *)inbuf2; req2->chain_fsp = req->chain_fsp; /* process the request */ @@ -1925,8 +1934,6 @@ void smbd_process(void) process_smb(inbuf, inbuf_len, unread_bytes, encrypted); - TALLOC_FREE(inbuf); - num_smbs++; /* The timeout_processing function isn't run nearly diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 25480c6e3b..be39fd464d 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -208,7 +208,7 @@ NTSTATUS check_path_syntax_posix(char *path) ****************************************************************************/ size_t srvstr_get_path_wcard(TALLOC_CTX *ctx, - const char *inbuf, + const char *base_ptr, uint16 smb_flags2, char **pp_dest, const char *src, @@ -221,22 +221,8 @@ size_t srvstr_get_path_wcard(TALLOC_CTX *ctx, *pp_dest = NULL; - if (src_len == 0) { - ret = srvstr_pull_buf_talloc(ctx, - inbuf, - smb_flags2, - pp_dest, - src, - flags); - } else { - ret = srvstr_pull_talloc(ctx, - inbuf, - smb_flags2, - pp_dest, - src, - src_len, - flags); - } + ret = srvstr_pull_talloc(ctx, base_ptr, smb_flags2, pp_dest, src, + src_len, flags); if (!*pp_dest) { *err = NT_STATUS_INVALID_PARAMETER; @@ -268,7 +254,7 @@ size_t srvstr_get_path_wcard(TALLOC_CTX *ctx, ****************************************************************************/ size_t srvstr_get_path(TALLOC_CTX *ctx, - const char *inbuf, + const char *base_ptr, uint16 smb_flags2, char **pp_dest, const char *src, @@ -276,48 +262,27 @@ size_t srvstr_get_path(TALLOC_CTX *ctx, int flags, NTSTATUS *err) { - size_t ret; - - *pp_dest = NULL; - - if (src_len == 0) { - ret = srvstr_pull_buf_talloc(ctx, - inbuf, - smb_flags2, - pp_dest, - src, - flags); - } else { - ret = srvstr_pull_talloc(ctx, - inbuf, - smb_flags2, - pp_dest, - src, - src_len, - flags); - } - - if (!*pp_dest) { - *err = NT_STATUS_INVALID_PARAMETER; - return ret; - } - - if (smb_flags2 & FLAGS2_DFS_PATHNAMES) { - /* - * For a DFS path the function parse_dfs_path() - * will do the path processing, just make a copy. - */ - *err = NT_STATUS_OK; - return ret; - } + bool ignore; + return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src, + src_len, flags, err, &ignore); +} - if (lp_posix_pathnames()) { - *err = check_path_syntax_posix(*pp_dest); - } else { - *err = check_path_syntax(*pp_dest); - } +size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req, + char **pp_dest, const char *src, int flags, + NTSTATUS *err, bool *contains_wcard) +{ + return srvstr_get_path_wcard(mem_ctx, (char *)req->inbuf, req->flags2, + pp_dest, src, smbreq_bufrem(req, src), + flags, err, contains_wcard); +} - return ret; +size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req, + char **pp_dest, const char *src, int flags, + NTSTATUS *err) +{ + bool ignore; + return srvstr_get_path_req_wcard(mem_ctx, req, pp_dest, src, + flags, err, &ignore); } /**************************************************************************** @@ -517,26 +482,25 @@ void reply_tcon(struct smb_request *req) char *dev = NULL; int pwlen=0; NTSTATUS nt_status; - char *p; + const char *p; DATA_BLOB password_blob; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBtcon); - if (smb_buflen(req->inbuf) < 4) { + if (req->buflen < 4) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBtcon); return; } - p = smb_buf(req->inbuf)+1; - p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, - &service_buf, p, STR_TERMINATE) + 1; - pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, - &password, p, STR_TERMINATE) + 1; - p += pwlen; - p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, - &dev, p, STR_TERMINATE) + 1; + p = (const char *)req->buf + 1; + p += srvstr_pull_req_talloc(ctx, req, &service_buf, p, STR_TERMINATE); + p += 1; + pwlen = srvstr_pull_req_talloc(ctx, req, &password, p, STR_TERMINATE); + p += pwlen+1; + p += srvstr_pull_req_talloc(ctx, req, &dev, p, STR_TERMINATE); + p += 1; if (service_buf == NULL || password == NULL || dev == NULL) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -583,7 +547,7 @@ void reply_tcon(struct smb_request *req) void reply_tcon_and_X(struct smb_request *req) { connection_struct *conn = req->conn; - char *service = NULL; + const char *service = NULL; DATA_BLOB password; TALLOC_CTX *ctx = talloc_tos(); /* what the cleint thinks the device is */ @@ -593,7 +557,7 @@ void reply_tcon_and_X(struct smb_request *req) NTSTATUS nt_status; int passlen; char *path = NULL; - char *p, *q; + const char *p, *q; uint16 tcon_flags; START_PROFILE(SMBtconX); @@ -604,8 +568,8 @@ void reply_tcon_and_X(struct smb_request *req) return; } - passlen = SVAL(req->inbuf,smb_vwv3); - tcon_flags = SVAL(req->inbuf,smb_vwv2); + passlen = SVAL(req->vwv+3, 0); + tcon_flags = SVAL(req->vwv+2, 0); /* we might have to close an old one */ if ((tcon_flags & 0x1) && conn) { @@ -614,34 +578,31 @@ void reply_tcon_and_X(struct smb_request *req) conn = NULL; } - if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) { + if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) { reply_doserror(req, ERRDOS, ERRbuftoosmall); END_PROFILE(SMBtconX); return; } if (global_encrypted_passwords_negotiated) { - password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf), - passlen); + password = data_blob_talloc(talloc_tos(), req->buf, passlen); if (lp_security() == SEC_SHARE) { /* * Security = share always has a pad byte * after the password. */ - p = smb_buf(req->inbuf) + passlen + 1; + p = (const char *)req->buf + passlen + 1; } else { - p = smb_buf(req->inbuf) + passlen; + p = (const char *)req->buf + passlen; } } else { - password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf), - passlen+1); + password = data_blob_talloc(talloc_tos(), req->buf, passlen+1); /* Ensure correct termination */ password.data[passlen]=0; - p = smb_buf(req->inbuf) + passlen + 1; + p = (const char *)req->buf + passlen + 1; } - p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p, - STR_TERMINATE); + p += srvstr_pull_req_talloc(ctx, req, &path, p, STR_TERMINATE); if (path == NULL) { data_blob_clear_free(&password); @@ -669,7 +630,7 @@ void reply_tcon_and_X(struct smb_request *req) p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2, &client_devicetype, p, - MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII); + MIN(6, smbreq_bufrem(req, p)), STR_ASCII); if (client_devicetype == NULL) { data_blob_clear_free(&password); @@ -803,8 +764,8 @@ void reply_ioctl(struct smb_request *req) return; } - device = SVAL(req->inbuf,smb_vwv1); - function = SVAL(req->inbuf,smb_vwv2); + device = SVAL(req->vwv+1, 0); + function = SVAL(req->vwv+2, 0); ioctl_code = (device << 16) + function; DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code)); @@ -831,7 +792,7 @@ void reply_ioctl(struct smb_request *req) case IOCTL_QUERY_JOB_INFO: { files_struct *fsp = file_fsp( - req, SVAL(req->inbuf, smb_vwv0)); + req, SVAL(req->vwv+0, 0)); if (!fsp) { reply_doserror(req, ERRDOS, ERRbadfid); END_PROFILE(SMBioctl); @@ -860,10 +821,10 @@ void reply_ioctl(struct smb_request *req) Strange checkpath NTSTATUS mapping. ****************************************************************************/ -static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status) +static NTSTATUS map_checkpath_error(uint16_t flags2, NTSTATUS status) { /* Strange DOS error code semantics only for checkpath... */ - if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) { + if (!(flags2 & FLAGS2_32_BIT_ERROR_CODES)) { if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) { /* We need to map to ERRbadpath */ return NT_STATUS_OBJECT_PATH_NOT_FOUND; @@ -886,11 +847,11 @@ void reply_checkpath(struct smb_request *req) START_PROFILE(SMBcheckpath); - srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name, - smb_buf(req->inbuf) + 1, 0, - STR_TERMINATE, &status); + srvstr_get_path_req(ctx, req, &name, (const char *)req->buf + 1, + STR_TERMINATE, &status); + if (!NT_STATUS_IS_OK(status)) { - status = map_checkpath_error((char *)req->inbuf, status); + status = map_checkpath_error(req->flags2, status); reply_nterror(req, status); END_PROFILE(SMBcheckpath); return; @@ -910,7 +871,7 @@ void reply_checkpath(struct smb_request *req) goto path_err; } - DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0))); + DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0))); status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf); if (!NT_STATUS_IS_OK(status)) { @@ -950,7 +911,7 @@ void reply_checkpath(struct smb_request *req) one at a time - if a component fails it expects ERRbadpath, not ERRbadfile. */ - status = map_checkpath_error((char *)req->inbuf, status); + status = map_checkpath_error(req->flags2, status); if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { /* * Windows returns different error codes if @@ -979,15 +940,14 @@ void reply_getatr(struct smb_request *req) int mode=0; SMB_OFF_T size=0; time_t mtime=0; - char *p; + const char *p; NTSTATUS status; TALLOC_CTX *ctx = talloc_tos(); START_PROFILE(SMBgetatr); - p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p, - 0, STR_TERMINATE, &status); + p = (const char *)req->buf + 1; + p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBgetatr); @@ -1081,7 +1041,7 @@ void reply_setatr(struct smb_request *req) int mode; time_t mtime; SMB_STRUCT_STAT sbuf; - char *p; + const char *p; NTSTATUS status; TALLOC_CTX *ctx = talloc_tos(); @@ -1094,9 +1054,8 @@ void reply_setatr(struct smb_request *req) return; } - p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p, - 0, STR_TERMINATE, &status); + p = (const char *)req->buf + 1; + p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBsetatr); @@ -1143,8 +1102,8 @@ void reply_setatr(struct smb_request *req) return; } - mode = SVAL(req->inbuf,smb_vwv0); - mtime = srv_make_unix_date3(req->inbuf+smb_vwv1); + mode = SVAL(req->vwv+0, 0); + mtime = srv_make_unix_date3(req->vwv+1); ts[1] = convert_time_t_to_timespec(mtime); status = smb_set_file_time(conn, NULL, fname, @@ -1236,7 +1195,7 @@ void reply_dskattr(struct smb_request *req) void reply_search(struct smb_request *req) { connection_struct *conn = req->conn; - char *mask = NULL; + const char *mask = NULL; char *directory = NULL; char *fname = NULL; SMB_OFF_T size; @@ -1246,7 +1205,7 @@ void reply_search(struct smb_request *req) unsigned int numentries = 0; unsigned int maxentries = 0; bool finished = False; - char *p; + const char *p; int status_len; char *path = NULL; char status[21]; @@ -1268,29 +1227,22 @@ void reply_search(struct smb_request *req) } if (lp_posix_pathnames()) { - reply_unknown_new(req, CVAL(req->inbuf, smb_com)); + reply_unknown_new(req, req->cmd); END_PROFILE(SMBsearch); return; } /* If we were called as SMBffirst then we must expect close. */ - if(CVAL(req->inbuf,smb_com) == SMBffirst) { + if(req->cmd == SMBffirst) { expect_close = True; } reply_outbuf(req, 1, 3); - maxentries = SVAL(req->inbuf,smb_vwv0); - dirtype = SVAL(req->inbuf,smb_vwv1); - p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard(ctx, - (char *)req->inbuf, - req->flags2, - &path, - p, - 0, - STR_TERMINATE, - &nt_status, - &mask_contains_wcard); + maxentries = SVAL(req->vwv+0, 0); + dirtype = SVAL(req->vwv+1, 0); + p = (const char *)req->buf + 1; + p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE, + &nt_status, &mask_contains_wcard); if (!NT_STATUS_IS_OK(nt_status)) { reply_nterror(req, nt_status); END_PROFILE(SMBsearch); @@ -1339,27 +1291,21 @@ void reply_search(struct smb_request *req) } p = strrchr_m(directory,'/'); - if (!p) { + if ((p != NULL) && (*directory != '/')) { + mask = p + 1; + directory = talloc_strndup(ctx, directory, + PTR_DIFF(p, directory)); + } else { mask = directory; directory = talloc_strdup(ctx,"."); - if (!directory) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; - } - } else { - *p = 0; - mask = p+1; } - if (*directory == '\0') { - directory = talloc_strdup(ctx,"."); - if (!directory) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBsearch); - return; - } + if (!directory) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBsearch); + return; } + memset((char *)status,'\0',21); SCVAL(status,0,(dirtype & 0x1F)); @@ -1497,7 +1443,7 @@ void reply_search(struct smb_request *req) } /* If we were called as SMBfunique, then we can close the dirptr now ! */ - if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) { + if(dptr_num >= 0 && req->cmd == SMBfunique) { dptr_close(&dptr_num); } @@ -1530,7 +1476,7 @@ void reply_search(struct smb_request *req) } DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n", - smb_fn_name(CVAL(req->inbuf,smb_com)), + smb_fn_name(req->cmd), mask, directory ? directory : "./", dirtype, @@ -1550,7 +1496,7 @@ void reply_fclose(struct smb_request *req) int status_len; char status[21]; int dptr_num= -2; - char *p; + const char *p; char *path = NULL; NTSTATUS err; bool path_contains_wcard = False; @@ -1559,21 +1505,14 @@ void reply_fclose(struct smb_request *req) START_PROFILE(SMBfclose); if (lp_posix_pathnames()) { - reply_unknown_new(req, CVAL(req->inbuf, smb_com)); + reply_unknown_new(req, req->cmd); END_PROFILE(SMBfclose); return; } - p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard(ctx, - (char *)req->inbuf, - req->flags2, - &path, - p, - 0, - STR_TERMINATE, - &err, - &path_contains_wcard); + p = (const char *)req->buf + 1; + p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE, + &err, &path_contains_wcard); if (!NT_STATUS_IS_OK(err)) { reply_nterror(req, err); END_PROFILE(SMBfclose); @@ -1638,12 +1577,11 @@ void reply_open(struct smb_request *req) } oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); - deny_mode = SVAL(req->inbuf,smb_vwv0); - dos_attr = SVAL(req->inbuf,smb_vwv1); + deny_mode = SVAL(req->vwv+0, 0); + dos_attr = SVAL(req->vwv+1, 0); - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, - smb_buf(req->inbuf)+1, 0, - STR_TERMINATE, &status); + srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBopen); @@ -1739,8 +1677,8 @@ void reply_open_and_X(struct smb_request *req) int core_oplock_request; int oplock_request; #if 0 - int smb_sattr = SVAL(req->inbuf,smb_vwv4); - uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6); + int smb_sattr = SVAL(req->vwv+4, 0); + uint32 smb_time = make_unix_date3(req->vwv+6); #endif int smb_ofun; uint32 fattr=0; @@ -1765,14 +1703,14 @@ void reply_open_and_X(struct smb_request *req) return; } - open_flags = SVAL(req->inbuf,smb_vwv2); - deny_mode = SVAL(req->inbuf,smb_vwv3); - smb_attr = SVAL(req->inbuf,smb_vwv5); + open_flags = SVAL(req->vwv+2, 0); + deny_mode = SVAL(req->vwv+3, 0); + smb_attr = SVAL(req->vwv+5, 0); ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf); core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); oplock_request = ex_oplock_request | core_oplock_request; - smb_ofun = SVAL(req->inbuf,smb_vwv8); - allocation_size = (uint64_t)IVAL(req->inbuf,smb_vwv9); + smb_ofun = SVAL(req->vwv+8, 0); + allocation_size = (uint64_t)IVAL(req->vwv+9, 0); /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(conn)) { @@ -1786,9 +1724,8 @@ void reply_open_and_X(struct smb_request *req) } /* XXXX we need to handle passed times, sattr and flags */ - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, - smb_buf(req->inbuf), 0, STR_TERMINATE, - &status); + srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBopenX); @@ -1954,7 +1891,6 @@ void reply_mknew(struct smb_request *req) { connection_struct *conn = req->conn; char *fname = NULL; - int com; uint32 fattr = 0; struct timespec ts[2]; files_struct *fsp; @@ -1975,17 +1911,14 @@ void reply_mknew(struct smb_request *req) return; } - fattr = SVAL(req->inbuf,smb_vwv0); + fattr = SVAL(req->vwv+0, 0); oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); - com = SVAL(req->inbuf,smb_com); - ts[1] =convert_time_t_to_timespec( - srv_make_unix_date3(req->inbuf + smb_vwv1)); + ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1)); /* mtime. */ - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, - smb_buf(req->inbuf) + 1, 0, - STR_TERMINATE, &status); + srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBcreate); @@ -1997,7 +1930,7 @@ void reply_mknew(struct smb_request *req) "please report this\n", fname)); } - if(com == SMBmknew) { + if(req->cmd == SMBmknew) { /* We should fail if file exists. */ create_disposition = FILE_CREATE; } else { @@ -2086,12 +2019,11 @@ void reply_ctemp(struct smb_request *req) return; } - fattr = SVAL(req->inbuf,smb_vwv0); + fattr = SVAL(req->vwv+0, 0); oplock_request = CORE_OPLOCK_REQUEST(req->inbuf); - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, - smb_buf(req->inbuf)+1, 0, STR_TERMINATE, - &status); + srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBctemp); @@ -2558,11 +2490,11 @@ void reply_unlink(struct smb_request *req) return; } - dirtype = SVAL(req->inbuf,smb_vwv0); + dirtype = SVAL(req->vwv+0, 0); - srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, - smb_buf(req->inbuf) + 1, 0, - STR_TERMINATE, &status, &path_contains_wcard); + srvstr_get_path_req_wcard(ctx, req, &name, (const char *)req->buf + 1, + STR_TERMINATE, &status, + &path_contains_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBunlink); @@ -2813,7 +2745,7 @@ void reply_readbraw(struct smb_request *req) * return a zero length response here. */ - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); /* * We have to do a check_fsp by hand here, as @@ -2829,7 +2761,7 @@ void reply_readbraw(struct smb_request *req) */ DEBUG(3,("reply_readbraw: fnum %d not valid " "- cache prime?\n", - (int)SVAL(req->inbuf,smb_vwv0))); + (int)SVAL(req->vwv+0, 0))); reply_readbraw_error(); END_PROFILE(SMBreadbraw); return; @@ -2840,7 +2772,7 @@ void reply_readbraw(struct smb_request *req) ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) && (fsp->access_mask & FILE_EXECUTE)))) { DEBUG(3,("reply_readbraw: fnum %d not readable.\n", - (int)SVAL(req->inbuf,smb_vwv0))); + (int)SVAL(req->vwv+0, 0))); reply_readbraw_error(); END_PROFILE(SMBreadbraw); return; @@ -2848,14 +2780,14 @@ void reply_readbraw(struct smb_request *req) flush_write_cache(fsp, READRAW_FLUSH); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0); if(req->wct == 10) { /* * This is a large offset (64 bit) read. */ #ifdef LARGE_SMB_OFF_T - startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32); + startpos |= (((SMB_OFF_T)IVAL(req->vwv+8, 0)) << 32); #else /* !LARGE_SMB_OFF_T */ @@ -2863,11 +2795,11 @@ void reply_readbraw(struct smb_request *req) * Ensure we haven't been sent a >32 bit offset. */ - if(IVAL(req->inbuf,smb_vwv8) != 0) { + if(IVAL(req->vwv+8, 0) != 0) { DEBUG(0,("reply_readbraw: large offset " "(%x << 32) used and we don't support " "64 bit offsets.\n", - (unsigned int)IVAL(req->inbuf,smb_vwv8) )); + (unsigned int)IVAL(req->vwv+8, 0) )); reply_readbraw_error(); END_PROFILE(SMBreadbraw); return; @@ -2885,8 +2817,8 @@ void reply_readbraw(struct smb_request *req) } } - maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF); - mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF); + maxcount = (SVAL(req->vwv+3, 0) & 0xFFFF); + mincount = (SVAL(req->vwv+4, 0) & 0xFFFF); /* ensure we don't overrun the packet size */ maxcount = MIN(65535,maxcount); @@ -2955,14 +2887,14 @@ void reply_lockread(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBlockread); return; } - if (!CHECK_READ(fsp,req->inbuf)) { + if (!CHECK_READ(fsp,req)) { reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBlockread); return; @@ -2970,8 +2902,8 @@ void reply_lockread(struct smb_request *req) release_level_2_oplocks_on_change(fsp); - numtoread = SVAL(req->inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); + numtoread = SVAL(req->vwv+1, 0); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread); @@ -3063,21 +2995,21 @@ void reply_read(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBread); return; } - if (!CHECK_READ(fsp,req->inbuf)) { + if (!CHECK_READ(fsp,req)) { reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBread); return; } - numtoread = SVAL(req->inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); + numtoread = SVAL(req->vwv+1, 0); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); numtoread = MIN(BUFFER_SIZE-outsize,numtoread); @@ -3183,7 +3115,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, * on a train in Germany :-). JRA. */ - if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) && + if ((chain_size == 0) && (CVAL(req->vwv+0, 0) == 0xFF) && !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) && lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) { uint8 headerbuf[smb_size + 12 * 2]; @@ -3197,7 +3129,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, header = data_blob_const(headerbuf, sizeof(headerbuf)); - construct_reply_common((char *)req->inbuf, (char *)headerbuf); + construct_reply_common_req(req, (char *)headerbuf); setup_readX_header((char *)headerbuf, smb_maxcnt); if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) { @@ -3249,7 +3181,7 @@ normal_read: if ((smb_maxcnt & 0xFF0000) > 0x10000) { uint8 headerbuf[smb_size + 2*12]; - construct_reply_common((char *)req->inbuf, (char *)headerbuf); + construct_reply_common_req(req, (char *)headerbuf); setup_readX_header((char *)headerbuf, smb_maxcnt); /* Send out the header. */ @@ -3297,7 +3229,7 @@ void reply_read_and_X(struct smb_request *req) size_t smb_maxcnt; bool big_readX = False; #if 0 - size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6); + size_t smb_mincnt = SVAL(req->vwv+6, 0); #endif START_PROFILE(SMBreadX); @@ -3307,9 +3239,9 @@ void reply_read_and_X(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2)); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3); - smb_maxcnt = SVAL(req->inbuf,smb_vwv5); + fsp = file_fsp(req, SVAL(req->vwv+2, 0)); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0); + smb_maxcnt = SVAL(req->vwv+5, 0); /* If it's an IPC, pass off the pipe handler. */ if (IS_IPC(conn)) { @@ -3323,18 +3255,18 @@ void reply_read_and_X(struct smb_request *req) return; } - if (!CHECK_READ(fsp,req->inbuf)) { + if (!CHECK_READ(fsp,req)) { reply_doserror(req, ERRDOS,ERRbadaccess); END_PROFILE(SMBreadX); return; } if (global_client_caps & CAP_LARGE_READX) { - size_t upper_size = SVAL(req->inbuf,smb_vwv7); + size_t upper_size = SVAL(req->vwv+7, 0); smb_maxcnt |= (upper_size<<16); if (upper_size > 1) { /* Can't do this on a chained packet. */ - if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) { + if ((CVAL(req->vwv+0, 0) != 0xFF)) { reply_nterror(req, NT_STATUS_NOT_SUPPORTED); END_PROFILE(SMBreadX); return; @@ -3361,7 +3293,7 @@ void reply_read_and_X(struct smb_request *req) /* * This is a large offset (64 bit) read. */ - startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32); + startpos |= (((SMB_OFF_T)IVAL(req->vwv+10, 0)) << 32); #else /* !LARGE_SMB_OFF_T */ @@ -3369,10 +3301,10 @@ void reply_read_and_X(struct smb_request *req) * Ensure we haven't been sent a >32 bit offset. */ - if(IVAL(req->inbuf,smb_vwv10) != 0) { + if(IVAL(req->vwv+10, 0) != 0) { DEBUG(0,("reply_read_and_X - large offset (%x << 32) " "used and we don't support 64 bit offsets.\n", - (unsigned int)IVAL(req->inbuf,smb_vwv10) )); + (unsigned int)IVAL(req->vwv+10, 0) )); END_PROFILE(SMBreadX); reply_doserror(req, ERRDOS, ERRbadaccess); return; @@ -3455,7 +3387,7 @@ void reply_writebraw(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { error_to_writebrawerr(req); END_PROFILE(SMBwritebraw); @@ -3469,9 +3401,9 @@ void reply_writebraw(struct smb_request *req) return; } - tcount = IVAL(req->inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3); - write_through = BITSETW(req->inbuf+smb_vwv7,0); + tcount = IVAL(req->vwv+1, 0); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0); + write_through = BITSETW(req->vwv+7,0); /* We have to deal with slightly different formats depending on whether we are using the core+ or lanman1.0 protocol */ @@ -3480,8 +3412,8 @@ void reply_writebraw(struct smb_request *req) numtowrite = SVAL(smb_buf(req->inbuf),-2); data = smb_buf(req->inbuf); } else { - numtowrite = SVAL(req->inbuf,smb_vwv10); - data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11); + numtowrite = SVAL(req->vwv+10, 0); + data = smb_base(req->inbuf) + SVAL(req->vwv+11, 0); } /* Ensure we don't write bytes past the end of this packet. */ @@ -3648,7 +3580,7 @@ void reply_writeunlock(struct smb_request *req) ssize_t nwritten = -1; size_t numtowrite; SMB_OFF_T startpos; - char *data; + const char *data; NTSTATUS status = NT_STATUS_OK; files_struct *fsp; @@ -3660,7 +3592,7 @@ void reply_writeunlock(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwriteunlock); @@ -3673,9 +3605,9 @@ void reply_writeunlock(struct smb_request *req) return; } - numtowrite = SVAL(req->inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); - data = smb_buf(req->inbuf) + 3; + numtowrite = SVAL(req->vwv+1, 0); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); + data = (const char *)req->buf + 3; if (numtowrite && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, @@ -3748,7 +3680,7 @@ void reply_write(struct smb_request *req) size_t numtowrite; ssize_t nwritten = -1; SMB_OFF_T startpos; - char *data; + const char *data; files_struct *fsp; NTSTATUS status; @@ -3767,7 +3699,7 @@ void reply_write(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwrite); @@ -3780,9 +3712,9 @@ void reply_write(struct smb_request *req) return; } - numtowrite = SVAL(req->inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); - data = smb_buf(req->inbuf) + 3; + numtowrite = SVAL(req->vwv+1, 0); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); + data = (const char *)req->buf + 3; if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, (uint64_t)startpos, WRITE_LOCK)) { @@ -3954,14 +3886,14 @@ void reply_write_and_X(struct smb_request *req) return; } - numtowrite = SVAL(req->inbuf,smb_vwv10); - smb_doff = SVAL(req->inbuf,smb_vwv11); + numtowrite = SVAL(req->vwv+10, 0); + smb_doff = SVAL(req->vwv+11, 0); smblen = smb_len(req->inbuf); if (req->unread_bytes > 0xFFFF || (smblen > smb_doff && smblen - smb_doff > 0xFFFF)) { - numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16); + numtowrite |= (((size_t)SVAL(req->vwv+9, 0))<<16); } if (req->unread_bytes) { @@ -3997,9 +3929,9 @@ void reply_write_and_X(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2)); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3); - write_through = BITSETW(req->inbuf+smb_vwv7,0); + fsp = file_fsp(req, SVAL(req->vwv+2, 0)); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0); + write_through = BITSETW(req->vwv+7,0); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwriteX); @@ -4019,7 +3951,7 @@ void reply_write_and_X(struct smb_request *req) /* * This is a large offset (64 bit) write. */ - startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32); + startpos |= (((SMB_OFF_T)IVAL(req->vwv+12, 0)) << 32); #else /* !LARGE_SMB_OFF_T */ @@ -4027,10 +3959,10 @@ void reply_write_and_X(struct smb_request *req) * Ensure we haven't been sent a >32 bit offset. */ - if(IVAL(req->inbuf,smb_vwv12) != 0) { + if(IVAL(req->vwv+12, 0) != 0) { DEBUG(0,("reply_write_and_X - large offset (%x << 32) " "used and we don't support 64 bit offsets.\n", - (unsigned int)IVAL(req->inbuf,smb_vwv12) )); + (unsigned int)IVAL(req->vwv+12, 0) )); reply_doserror(req, ERRDOS, ERRbadaccess); END_PROFILE(SMBwriteX); return; @@ -4118,7 +4050,7 @@ void reply_lseek(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { return; @@ -4126,9 +4058,9 @@ void reply_lseek(struct smb_request *req) flush_write_cache(fsp, SEEK_FLUSH); - mode = SVAL(req->inbuf,smb_vwv1) & 3; + mode = SVAL(req->vwv+1, 0) & 3; /* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */ - startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2); + startpos = (SMB_OFF_T)IVALS(req->vwv+2, 0); switch (mode) { case 0: @@ -4203,7 +4135,7 @@ void reply_flush(struct smb_request *req) return; } - fnum = SVAL(req->inbuf,smb_vwv0); + fnum = SVAL(req->vwv+0, 0); fsp = file_fsp(req, fnum); if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) { @@ -4266,7 +4198,7 @@ void reply_close(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); /* * We can only use check_fsp if we know it's not a directory. @@ -4298,7 +4230,7 @@ void reply_close(struct smb_request *req) * Take care of any time sent in the close. */ - t = srv_make_unix_date3(req->inbuf+smb_vwv1); + t = srv_make_unix_date3(req->vwv+1); set_close_write_time(fsp, convert_time_t_to_timespec(t)); /* @@ -4332,7 +4264,7 @@ void reply_writeclose(struct smb_request *req) ssize_t nwritten = -1; NTSTATUS close_status = NT_STATUS_OK; SMB_OFF_T startpos; - char *data; + const char *data; struct timespec mtime; files_struct *fsp; @@ -4344,7 +4276,7 @@ void reply_writeclose(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBwriteclose); @@ -4356,11 +4288,10 @@ void reply_writeclose(struct smb_request *req) return; } - numtowrite = SVAL(req->inbuf,smb_vwv1); - startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2); - mtime = convert_time_t_to_timespec(srv_make_unix_date3( - req->inbuf+smb_vwv4)); - data = smb_buf(req->inbuf) + 1; + numtowrite = SVAL(req->vwv+1, 0); + startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0); + mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4)); + data = (const char *)req->buf + 1; if (numtowrite && is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite, @@ -4431,7 +4362,7 @@ void reply_lock(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBlock); @@ -4440,8 +4371,8 @@ void reply_lock(struct smb_request *req) release_level_2_oplocks_on_change(fsp); - count = (uint64_t)IVAL(req->inbuf,smb_vwv1); - offset = (uint64_t)IVAL(req->inbuf,smb_vwv3); + count = (uint64_t)IVAL(req->vwv+1, 0); + offset = (uint64_t)IVAL(req->vwv+3, 0); DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n", fsp->fh->fd, fsp->fnum, (double)offset, (double)count)); @@ -4490,15 +4421,15 @@ void reply_unlock(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBunlock); return; } - count = (uint64_t)IVAL(req->inbuf,smb_vwv1); - offset = (uint64_t)IVAL(req->inbuf,smb_vwv3); + count = (uint64_t)IVAL(req->vwv+1, 0); + offset = (uint64_t)IVAL(req->vwv+3, 0); status = do_unlock(smbd_messaging_context(), fsp, @@ -4562,7 +4493,6 @@ void reply_echo(struct smb_request *req) connection_struct *conn = req->conn; int smb_reverb; int seq_num; - unsigned int data_len = smb_buflen(req->inbuf); START_PROFILE(SMBecho); @@ -4572,20 +4502,13 @@ void reply_echo(struct smb_request *req) return; } - if (data_len > BUFFER_SIZE) { - DEBUG(0,("reply_echo: data_len too large.\n")); - reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES); - END_PROFILE(SMBecho); - return; - } + smb_reverb = SVAL(req->vwv+0, 0); - smb_reverb = SVAL(req->inbuf,smb_vwv0); - - reply_outbuf(req, 1, data_len); + reply_outbuf(req, 1, req->buflen); /* copy any incoming data back out */ - if (data_len > 0) { - memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len); + if (req->buflen > 0) { + memcpy(smb_buf(req->outbuf), req->buf, req->buflen); } if (smb_reverb > 100) { @@ -4672,7 +4595,7 @@ void reply_printclose(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBsplclose); @@ -4720,8 +4643,8 @@ void reply_printqueue(struct smb_request *req) return; } - max_count = SVAL(req->inbuf,smb_vwv0); - start_index = SVAL(req->inbuf,smb_vwv1); + max_count = SVAL(req->vwv+0, 0); + start_index = SVAL(req->vwv+1, 0); /* we used to allow the client to get the cnum wrong, but that is really quite gross and only worked when there was only @@ -4803,7 +4726,7 @@ void reply_printwrite(struct smb_request *req) { connection_struct *conn = req->conn; int numtowrite; - char *data; + const char *data; files_struct *fsp; START_PROFILE(SMBsplwr); @@ -4814,7 +4737,7 @@ void reply_printwrite(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if (!check_fsp(conn, req, fsp)) { END_PROFILE(SMBsplwr); @@ -4833,15 +4756,15 @@ void reply_printwrite(struct smb_request *req) return; } - numtowrite = SVAL(smb_buf(req->inbuf),1); + numtowrite = SVAL(req->buf, 1); - if (smb_buflen(req->inbuf) < numtowrite + 3) { + if (req->buflen < numtowrite + 3) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBsplwr); return; } - data = smb_buf(req->inbuf) + 3; + data = (const char *)req->buf + 3; if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) { reply_unixerror(req, ERRHRD, ERRdiskfull); @@ -4869,9 +4792,8 @@ void reply_mkdir(struct smb_request *req) START_PROFILE(SMBmkdir); - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory, - smb_buf(req->inbuf) + 1, 0, - STR_TERMINATE, &status); + srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBmkdir); @@ -5140,9 +5062,8 @@ void reply_rmdir(struct smb_request *req) START_PROFILE(SMBrmdir); - srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory, - smb_buf(req->inbuf) + 1, 0, - STR_TERMINATE, &status); + srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1, + STR_TERMINATE, &status); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBrmdir); @@ -5922,7 +5843,7 @@ void reply_mv(struct smb_request *req) connection_struct *conn = req->conn; char *name = NULL; char *newname = NULL; - char *p; + const char *p; uint32 attrs; NTSTATUS status; bool src_has_wcard = False; @@ -5937,21 +5858,19 @@ void reply_mv(struct smb_request *req) return; } - attrs = SVAL(req->inbuf,smb_vwv0); + attrs = SVAL(req->vwv+0, 0); - p = smb_buf(req->inbuf) + 1; - p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p, - 0, STR_TERMINATE, &status, - &src_has_wcard); + p = (const char *)req->buf + 1; + p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE, + &status, &src_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBmv); return; } p++; - p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, - 0, STR_TERMINATE, &status, - &dest_has_wcard); + p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE, + &status, &dest_has_wcard); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBmv); @@ -6155,8 +6074,9 @@ void reply_copy(struct smb_request *req) char *name = NULL; char *newname = NULL; char *directory = NULL; - char *mask = NULL; - char *p; + const char *mask = NULL; + const char mask_star[] = "*"; + const char *p; int count=0; int error = ERRnoaccess; int err = 0; @@ -6178,22 +6098,20 @@ void reply_copy(struct smb_request *req) return; } - tid2 = SVAL(req->inbuf,smb_vwv0); - ofun = SVAL(req->inbuf,smb_vwv1); - flags = SVAL(req->inbuf,smb_vwv2); + tid2 = SVAL(req->vwv+0, 0); + ofun = SVAL(req->vwv+1, 0); + flags = SVAL(req->vwv+2, 0); - p = smb_buf(req->inbuf); - p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p, - 0, STR_TERMINATE, &status, - &source_has_wild); + p = (const char *)req->buf; + p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE, + &status, &source_has_wild); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBcopy); return; } - p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p, - 0, STR_TERMINATE, &status, - &dest_has_wild); + p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE, + &status, &dest_has_wild); if (!NT_STATUS_IS_OK(status)) { reply_nterror(req, status); END_PROFILE(SMBcopy); @@ -6283,23 +6201,18 @@ void reply_copy(struct smb_request *req) } p = strrchr_m(name,'/'); - if (!p) { + if (p != NULL) { + directory = talloc_strndup(ctx, name, PTR_DIFF(p, name)); + mask = p+1; + } else { directory = talloc_strdup(ctx, "./"); - if (!directory) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBcopy); - return; - } mask = name; - } else { - *p = 0; - directory = talloc_strdup(ctx, name); - if (!directory) { - reply_nterror(req, NT_STATUS_NO_MEMORY); - END_PROFILE(SMBcopy); - return; - } - mask = p+1; + } + + if (!directory) { + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBcopy); + return; } /* @@ -6367,8 +6280,7 @@ void reply_copy(struct smb_request *req) long offset = 0; if (strequal(mask,"????????.???")) { - mask[0] = '*'; - mask[1] = '\0'; + mask = mask_star; } status = check_name(conn, directory); @@ -6484,7 +6396,8 @@ void reply_copy(struct smb_request *req) Get a lock pid, dealing with large count requests. ****************************************************************************/ -uint32 get_lock_pid( char *data, int data_offset, bool large_file_format) +uint32 get_lock_pid(const uint8_t *data, int data_offset, + bool large_file_format) { if(!large_file_format) return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset)); @@ -6496,7 +6409,8 @@ uint32 get_lock_pid( char *data, int data_offset, bool large_file_format) Get a lock count, dealing with large count requests. ****************************************************************************/ -uint64_t get_lock_count( char *data, int data_offset, bool large_file_format) +uint64_t get_lock_count(const uint8_t *data, int data_offset, + bool large_file_format) { uint64_t count = 0; @@ -6568,7 +6482,8 @@ static uint32 map_lock_offset(uint32 high, uint32 low) Get a lock offset, dealing with large offset requests. ****************************************************************************/ -uint64_t get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err) +uint64_t get_lock_offset(const uint8_t *data, int data_offset, + bool large_file_format, bool *err) { uint64_t offset = 0; @@ -6629,7 +6544,7 @@ void reply_lockingX(struct smb_request *req) uint32 lock_pid; int32 lock_timeout; int i; - char *data; + const uint8_t *data; bool large_file_format; bool err; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -6642,12 +6557,12 @@ void reply_lockingX(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2)); - locktype = CVAL(req->inbuf,smb_vwv3); - oplocklevel = CVAL(req->inbuf,smb_vwv3+1); - num_ulocks = SVAL(req->inbuf,smb_vwv6); - num_locks = SVAL(req->inbuf,smb_vwv7); - lock_timeout = IVAL(req->inbuf,smb_vwv4); + fsp = file_fsp(req, SVAL(req->vwv+2, 0)); + locktype = CVAL(req->vwv+3, 0); + oplocklevel = CVAL(req->vwv+3, 1); + num_ulocks = SVAL(req->vwv+6, 0); + num_locks = SVAL(req->vwv+7, 0); + lock_timeout = IVAL(req->vwv+4, 0); large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False; if (!check_fsp(conn, req, fsp)) { @@ -6655,7 +6570,7 @@ void reply_lockingX(struct smb_request *req) return; } - data = smb_buf(req->inbuf); + data = req->buf; if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) { /* we don't support these - and CANCEL_LOCK makes w2k @@ -6729,11 +6644,10 @@ void reply_lockingX(struct smb_request *req) if (num_locks == 0 && num_ulocks == 0) { /* Sanity check - ensure a pure oplock break is not a chained request. */ - if(CVAL(req->inbuf,smb_vwv0) != 0xff) + if(CVAL(req->vwv+0, 0) != 0xff) DEBUG(0,("reply_lockingX: Error : pure oplock " "break is a chained %d request !\n", - (unsigned int)CVAL(req->inbuf, - smb_vwv0) )); + (unsigned int)CVAL(req->vwv+0, 0))); END_PROFILE(SMBlockingX); return; } @@ -6746,7 +6660,7 @@ void reply_lockingX(struct smb_request *req) release_level_2_oplocks_on_change(fsp); - if (smb_buflen(req->inbuf) < + if (req->buflen < (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBlockingX); @@ -7018,7 +6932,7 @@ void reply_setattrE(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if(!fsp || (fsp->conn != conn)) { reply_doserror(req, ERRDOS, ERRbadfid); @@ -7033,9 +6947,9 @@ void reply_setattrE(struct smb_request *req) */ ts[0] = convert_time_t_to_timespec( - srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */ + srv_make_unix_date2(req->vwv+3)); /* atime. */ ts[1] = convert_time_t_to_timespec( - srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */ + srv_make_unix_date2(req->vwv+5)); /* mtime. */ reply_outbuf(req, 0, 0); @@ -7129,7 +7043,7 @@ void reply_getattrE(struct smb_request *req) return; } - fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0)); + fsp = file_fsp(req, SVAL(req->vwv+0, 0)); if(!fsp || (fsp->conn != conn)) { reply_doserror(req, ERRDOS, ERRbadfid); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 4e81263ee4..fff05a3aac 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -80,7 +80,7 @@ struct event_context *smbd_event_context(void) { static struct event_context *ctx; - if (!ctx && !(ctx = event_context_init(NULL))) { + if (!ctx && !(ctx = event_context_init(talloc_autofree_context()))) { smb_panic("Could not init smbd event context"); } return ctx; @@ -91,7 +91,7 @@ struct messaging_context *smbd_messaging_context(void) static struct messaging_context *ctx; if (ctx == NULL) { - ctx = messaging_init(NULL, server_id_self(), + ctx = messaging_init(talloc_autofree_context(), server_id_self(), smbd_event_context()); } if (ctx == NULL) { @@ -105,7 +105,7 @@ struct memcache *smbd_memcache(void) static struct memcache *cache; if (!cache - && !(cache = memcache_init(NULL, + && !(cache = memcache_init(talloc_autofree_context(), lp_max_stat_cache_size()*1024))) { smb_panic("Could not init smbd memcache"); @@ -1415,7 +1415,7 @@ extern void build_options(bool screen); } if (*lp_rootdir()) { - if (sys_chroot(lp_rootdir()) == 0) + if (chroot(lp_rootdir()) == 0) DEBUG(2,("Changed root to %s\n", lp_rootdir())); } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index a482b3398a..fde6cdc160 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -1161,23 +1161,25 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid, static void reply_sesssetup_and_X_spnego(struct smb_request *req) { - uint8 *p; + const uint8 *p; DATA_BLOB blob1; size_t bufrem; - fstring native_os, native_lanman, primary_domain; + char *tmp; + const char *native_os; + const char *native_lanman; + const char *primary_domain; const char *p2; - uint16 data_blob_len = SVAL(req->inbuf, smb_vwv7); + uint16 data_blob_len = SVAL(req->vwv+7, 0); enum remote_arch_types ra_type = get_remote_arch(); int vuid = SVAL(req->inbuf,smb_uid); user_struct *vuser = NULL; NTSTATUS status = NT_STATUS_OK; uint16 smbpid = req->smbpid; - uint16 smb_flag2 = req->flags2; DEBUG(3,("Doing spnego session setup\n")); if (global_client_caps == 0) { - global_client_caps = IVAL(req->inbuf,smb_vwv10); + global_client_caps = IVAL(req->vwv+10, 0); if (!(global_client_caps & CAP_STATUS32)) { remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); @@ -1185,7 +1187,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) } - p = (uint8 *)smb_buf(req->inbuf); + p = req->buf; if (data_blob_len == 0) { /* an invalid request */ @@ -1193,7 +1195,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) return; } - bufrem = smb_bufrem(req->inbuf, p); + bufrem = smbreq_bufrem(req, p); /* pull the spnego blob */ blob1 = data_blob(p, MIN(bufrem, data_blob_len)); @@ -1202,12 +1204,19 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) #endif p2 = (char *)req->inbuf + smb_vwv13 + data_blob_len; - p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_os, p2, - sizeof(native_os), STR_TERMINATE); - p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_lanman, p2, - sizeof(native_lanman), STR_TERMINATE); - p2 += srvstr_pull_buf(req->inbuf, smb_flag2, primary_domain, p2, - sizeof(primary_domain), STR_TERMINATE); + + p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2, + STR_TERMINATE); + native_os = tmp ? tmp : ""; + + p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2, + STR_TERMINATE); + native_lanman = tmp ? tmp : ""; + + p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2, + STR_TERMINATE); + primary_domain = tmp ? tmp : ""; + DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n", native_os, native_lanman, primary_domain)); @@ -1390,12 +1399,13 @@ void reply_sesssetup_and_X(struct smb_request *req) DATA_BLOB lm_resp; DATA_BLOB nt_resp; DATA_BLOB plaintext_password; - fstring user; + char *tmp; + const char *user; fstring sub_user; /* Sainitised username for substituion */ - fstring domain; - fstring native_os; - fstring native_lanman; - fstring primary_domain; + const char *domain; + const char *native_os; + const char *native_lanman; + const char *primary_domain; static bool done_sesssetup = False; auth_usersupplied_info *user_info = NULL; auth_serversupplied_info *server_info = NULL; @@ -1428,7 +1438,7 @@ void reply_sesssetup_and_X(struct smb_request *req) return; } - if (SVAL(req->inbuf,smb_vwv4) == 0) { + if (SVAL(req->vwv+4, 0) == 0) { setup_new_vc_session(); } @@ -1437,18 +1447,16 @@ void reply_sesssetup_and_X(struct smb_request *req) return; } - smb_bufsize = SVAL(req->inbuf,smb_vwv2); + smb_bufsize = SVAL(req->vwv+2, 0); if (Protocol < PROTOCOL_NT1) { - uint16 passlen1 = SVAL(req->inbuf,smb_vwv7); + uint16 passlen1 = SVAL(req->vwv+7, 0); /* Never do NT status codes with protocols before NT1 as we * don't get client caps. */ remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES); - if ((passlen1 > MAX_PASS_LEN) - || (passlen1 > smb_bufrem(req->inbuf, - smb_buf(req->inbuf)))) { + if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) { reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); END_PROFILE(SMBsesssetupX); @@ -1456,30 +1464,30 @@ void reply_sesssetup_and_X(struct smb_request *req) } if (doencrypt) { - lm_resp = data_blob(smb_buf(req->inbuf), passlen1); + lm_resp = data_blob(req->buf, passlen1); } else { - plaintext_password = data_blob(smb_buf(req->inbuf), - passlen1+1); + plaintext_password = data_blob(req->buf, passlen1+1); /* Ensure null termination */ plaintext_password.data[passlen1] = 0; } - srvstr_pull_buf(req->inbuf, req->flags2, user, - smb_buf(req->inbuf)+passlen1, sizeof(user), - STR_TERMINATE); - *domain = 0; + srvstr_pull_req_talloc(talloc_tos(), req, &tmp, + req->buf + passlen1, STR_TERMINATE); + user = tmp ? tmp : ""; + + domain = ""; } else { - uint16 passlen1 = SVAL(req->inbuf,smb_vwv7); - uint16 passlen2 = SVAL(req->inbuf,smb_vwv8); + uint16 passlen1 = SVAL(req->vwv+7, 0); + uint16 passlen2 = SVAL(req->vwv+8, 0); enum remote_arch_types ra_type = get_remote_arch(); - char *p = smb_buf(req->inbuf); - char *save_p = smb_buf(req->inbuf); + const uint8_t *p = req->buf; + const uint8_t *save_p = req->buf; uint16 byte_count; if(global_client_caps == 0) { - global_client_caps = IVAL(req->inbuf,smb_vwv11); + global_client_caps = IVAL(req->vwv+11, 0); if (!(global_client_caps & CAP_STATUS32)) { remove_from_common_flags2( @@ -1521,7 +1529,7 @@ void reply_sesssetup_and_X(struct smb_request *req) /* check for nasty tricks */ if (passlen1 > MAX_PASS_LEN - || passlen1 > smb_bufrem(req->inbuf, p)) { + || passlen1 > smbreq_bufrem(req, p)) { reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); END_PROFILE(SMBsesssetupX); @@ -1529,7 +1537,7 @@ void reply_sesssetup_and_X(struct smb_request *req) } if (passlen2 > MAX_PASS_LEN - || passlen2 > smb_bufrem(req->inbuf, p+passlen1)) { + || passlen2 > smbreq_bufrem(req, p+passlen1)) { reply_nterror(req, nt_status_squash( NT_STATUS_INVALID_PARAMETER)); END_PROFILE(SMBsesssetupX); @@ -1559,7 +1567,7 @@ void reply_sesssetup_and_X(struct smb_request *req) req->inbuf, req->flags2, &pass, - smb_buf(req->inbuf), + req->buf, passlen1, STR_TERMINATE|STR_ASCII); } else { @@ -1567,7 +1575,7 @@ void reply_sesssetup_and_X(struct smb_request *req) req->inbuf, req->flags2, &pass, - smb_buf(req->inbuf), + req->buf, unic ? passlen2 : passlen1, STR_TERMINATE); } @@ -1581,15 +1589,22 @@ void reply_sesssetup_and_X(struct smb_request *req) } p += passlen1 + passlen2; - p += srvstr_pull_buf(req->inbuf, req->flags2, user, p, - sizeof(user), STR_TERMINATE); - p += srvstr_pull_buf(req->inbuf, req->flags2, domain, p, - sizeof(domain), STR_TERMINATE); - p += srvstr_pull_buf(req->inbuf, req->flags2, native_os, - p, sizeof(native_os), STR_TERMINATE); - p += srvstr_pull_buf(req->inbuf, req->flags2, - native_lanman, p, sizeof(native_lanman), - STR_TERMINATE); + + p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p, + STR_TERMINATE); + user = tmp ? tmp : ""; + + p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p, + STR_TERMINATE); + domain = tmp ? tmp : ""; + + p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p, + STR_TERMINATE); + native_os = tmp ? tmp : ""; + + p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p, + STR_TERMINATE); + native_lanman = tmp ? tmp : ""; /* not documented or decoded by Ethereal but there is one more * string in the extra bytes which is the same as the @@ -1598,14 +1613,13 @@ void reply_sesssetup_and_X(struct smb_request *req) * Windows 9x does not include a string here at all so we have * to check if we have any extra bytes left */ - byte_count = SVAL(req->inbuf, smb_vwv13); + byte_count = SVAL(req->vwv+13, 0); if ( PTR_DIFF(p, save_p) < byte_count) { - p += srvstr_pull_buf(req->inbuf, req->flags2, - primary_domain, p, - sizeof(primary_domain), - STR_TERMINATE); + p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p, + STR_TERMINATE); + primary_domain = tmp ? tmp : ""; } else { - fstrcpy( primary_domain, "null" ); + primary_domain = talloc_strdup(talloc_tos(), "null"); } DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] " @@ -1621,7 +1635,7 @@ void reply_sesssetup_and_X(struct smb_request *req) } - if (SVAL(req->inbuf,smb_vwv4) == 0) { + if (SVAL(req->vwv+4, 0) == 0) { setup_new_vc_session(); } @@ -1662,7 +1676,7 @@ void reply_sesssetup_and_X(struct smb_request *req) add_session_user(sub_user); add_session_workgroup(domain); /* Then force it to null for the benfit of the code below */ - *user = 0; + user = ""; } if (!*user) { diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 1da45a8b58..c385c6ccb1 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -768,6 +768,12 @@ void send_trans2_replies(connection_struct *conn, reply_outbuf(req, 10, total_sent_thistime + alignment_offset + data_alignment_offset); + /* + * We might have SMBtrans2s in req which was transferred to + * the outbuf, fix that. + */ + SCVAL(req->outbuf, smb_com, SMBtrans2); + /* Set total params and data to be sent */ SSVAL(req->outbuf,smb_tprcnt,paramsize); SSVAL(req->outbuf,smb_tdrcnt,datasize); @@ -2183,7 +2189,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", - smb_fn_name(CVAL(req->inbuf,smb_com)), + smb_fn_name(req->cmd), mask, directory, dirtype, numentries ) ); /* @@ -2481,7 +2487,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd } DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n", - smb_fn_name(CVAL(req->inbuf,smb_com)), + smb_fn_name(req->cmd), mask, directory, dirtype, numentries ) ); /* Check if we can close the dirptr */ @@ -3118,7 +3124,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned max_data_bytes); DEBUG( 4, ( "%s info_level = %d\n", - smb_fn_name(CVAL(req->inbuf,smb_com)), info_level) ); + smb_fn_name(req->cmd), info_level) ); return; } @@ -3846,7 +3852,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, files_struct *fsp = NULL; struct file_id fileid; struct ea_list *ea_list = NULL; - uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */ char *lock_data = NULL; bool ms_dfs_link = false; TALLOC_CTX *ctx = talloc_tos(); @@ -3939,7 +3944,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn, pos = fsp->fh->position_information; fileid = vfs_file_id_from_sbuf(conn, &sbuf); get_file_infos(fileid, &delete_pending, &write_time_ts); - access_mask = fsp->access_mask; } } else { @@ -4403,7 +4407,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd case SMB_FILE_ACCESS_INFORMATION: DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n")); - SIVAL(pdata,0,access_mask); + if (fsp) { + SIVAL(pdata,0,fsp->access_mask); + } else { + /* GENERIC_EXECUTE mapping from Windows */ + SIVAL(pdata,0,0x12019F); + } data_size = 4; break; @@ -5470,7 +5479,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn, ****************************************************************************/ static NTSTATUS smb_set_posix_lock(connection_struct *conn, - const struct smb_request *req, + struct smb_request *req, const char *pdata, int total_data, files_struct *fsp) @@ -7251,7 +7260,7 @@ static void call_trans2ioctl(connection_struct *conn, unsigned int max_data_bytes) { char *pdata = *ppdata; - files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv15)); + files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0)); /* check for an invalid fid before proceeding */ @@ -7304,7 +7313,7 @@ void reply_findclose(struct smb_request *req) return; } - dptr_num = SVALS(req->inbuf,smb_vwv0); + dptr_num = SVALS(req->vwv+0, 0); DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num)); @@ -7334,7 +7343,7 @@ void reply_findnclose(struct smb_request *req) return; } - dptr_num = SVAL(req->inbuf,smb_vwv0); + dptr_num = SVAL(req->vwv+0, 0); DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num)); @@ -7537,11 +7546,11 @@ void reply_trans2(struct smb_request *req) return; } - dsoff = SVAL(req->inbuf, smb_dsoff); - dscnt = SVAL(req->inbuf, smb_dscnt); - psoff = SVAL(req->inbuf, smb_psoff); - pscnt = SVAL(req->inbuf, smb_pscnt); - tran_call = SVAL(req->inbuf, smb_setup0); + dsoff = SVAL(req->vwv+12, 0); + dscnt = SVAL(req->vwv+11, 0); + psoff = SVAL(req->vwv+10, 0); + pscnt = SVAL(req->vwv+9, 0); + tran_call = SVAL(req->vwv+14, 0); size = smb_len(req->inbuf) + 4; av_size = smb_len(req->inbuf); @@ -7581,17 +7590,17 @@ void reply_trans2(struct smb_request *req) state->mid = req->mid; state->vuid = req->vuid; - state->setup_count = SVAL(req->inbuf, smb_suwcnt); + state->setup_count = SVAL(req->vwv+13, 0); state->setup = NULL; - state->total_param = SVAL(req->inbuf, smb_tpscnt); + state->total_param = SVAL(req->vwv+0, 0); state->param = NULL; - state->total_data = SVAL(req->inbuf, smb_tdscnt); + state->total_data = SVAL(req->vwv+1, 0); state->data = NULL; - state->max_param_return = SVAL(req->inbuf, smb_mprcnt); - state->max_data_return = SVAL(req->inbuf, smb_mdrcnt); - state->max_setup_return = SVAL(req->inbuf, smb_msrcnt); - state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0); - state->one_way = BITSETW(req->inbuf+smb_vwv5,1); + state->max_param_return = SVAL(req->vwv+2, 0); + state->max_data_return = SVAL(req->vwv+3, 0); + state->max_setup_return = SVAL(req->vwv+4, 0); + state->close_on_completion = BITSETW(req->vwv+5, 0); + state->one_way = BITSETW(req->vwv+5, 1); state->call = tran_call; @@ -7755,18 +7764,18 @@ void reply_transs2(struct smb_request *req) /* Revise state->total_param and state->total_data in case they have changed downwards */ - if (SVAL(req->inbuf, smb_tpscnt) < state->total_param) - state->total_param = SVAL(req->inbuf, smb_tpscnt); - if (SVAL(req->inbuf, smb_tdscnt) < state->total_data) - state->total_data = SVAL(req->inbuf, smb_tdscnt); + if (SVAL(req->vwv+0, 0) < state->total_param) + state->total_param = SVAL(req->vwv+0, 0); + if (SVAL(req->vwv+1, 0) < state->total_data) + state->total_data = SVAL(req->vwv+1, 0); - pcnt = SVAL(req->inbuf, smb_spscnt); - poff = SVAL(req->inbuf, smb_spsoff); - pdisp = SVAL(req->inbuf, smb_spsdisp); + pcnt = SVAL(req->vwv+2, 0); + poff = SVAL(req->vwv+3, 0); + pdisp = SVAL(req->vwv+4, 0); - dcnt = SVAL(req->inbuf, smb_sdscnt); - doff = SVAL(req->inbuf, smb_sdsoff); - ddisp = SVAL(req->inbuf, smb_sdsdisp); + dcnt = SVAL(req->vwv+5, 0); + doff = SVAL(req->vwv+6, 0); + ddisp = SVAL(req->vwv+7, 0); state->received_param += pcnt; state->received_data += dcnt; @@ -7819,12 +7828,6 @@ void reply_transs2(struct smb_request *req) return; } - /* - * construct_reply_common will copy smb_com from inbuf to - * outbuf. SMBtranss2 is wrong here. - */ - SCVAL(req->inbuf,smb_com,SMBtrans2); - handle_trans2(conn, req, state); DLIST_REMOVE(conn->pending_trans, state); diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c index 8998f6a371..045de6f2d3 100644 --- a/source3/smbd/uid.c +++ b/source3/smbd/uid.c @@ -32,7 +32,7 @@ bool change_to_guest(void) if (!pass) { /* Don't need to free() this as its stored in a static */ - pass = getpwnam_alloc(NULL, lp_guestaccount()); + pass = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount()); if (!pass) return(False); } diff --git a/source3/torture/nsstest.c b/source3/torture/nsstest.c index 6bd0efe1af..352b3fa33c 100644 --- a/source3/torture/nsstest.c +++ b/source3/torture/nsstest.c @@ -37,13 +37,13 @@ static void *find_fn(const char *name) } if (!h) { - h = sys_dlopen(so_path, RTLD_LAZY); + h = dlopen(so_path, RTLD_LAZY); } if (!h) { printf("Can't open shared library %s\n", so_path); exit(1); } - res = sys_dlsym(h, s); + res = dlsym(h, s); if (!res) { printf("Can't find function %s\n", s); total_errors++; diff --git a/source3/utils/net_ads_gpo.c b/source3/utils/net_ads_gpo.c index 3c66325abe..181cba221d 100644 --- a/source3/utils/net_ads_gpo.c +++ b/source3/utils/net_ads_gpo.c @@ -107,7 +107,7 @@ static int net_ads_gpo_refresh(struct net_context *c, int argc, const char **arg WERROR werr = gp_reg_state_store(mem_ctx, flags, dn, token, gpo_list); if (!W_ERROR_IS_OK(werr)) { - d_printf("failed: %s\n", dos_errstr(werr)); + d_printf("failed: %s\n", win_errstr(werr)); goto out; } } @@ -152,7 +152,7 @@ static int net_ads_gpo_refresh(struct net_context *c, int argc, const char **arg &token->user_sids[0], &read_list); if (!W_ERROR_IS_OK(werr)) { - d_printf("failed: %s\n", dos_errstr(werr)); + d_printf("failed: %s\n", win_errstr(werr)); goto out; } } diff --git a/source3/utils/net_conf.c b/source3/utils/net_conf.c index ab1b0f3df7..31e87ca804 100644 --- a/source3/utils/net_conf.c +++ b/source3/utils/net_conf.c @@ -249,7 +249,7 @@ static int net_conf_list(struct net_context *c, struct smbconf_ctx *conf_ctx, werr = smbconf_get_config(conf_ctx, mem_ctx, &num_shares, &shares); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error getting config: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -322,7 +322,7 @@ static int net_conf_import(struct net_context *c, struct smbconf_ctx *conf_ctx, werr = smbconf_init(mem_ctx, &txt_ctx, conf_source); if (!W_ERROR_IS_OK(werr)) { d_printf("error loading file '%s': %s\n", filename, - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -425,7 +425,7 @@ static int net_conf_drop(struct net_context *c, struct smbconf_ctx *conf_ctx, werr = smbconf_drop(conf_ctx); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error deleting configuration: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -462,7 +462,7 @@ static int net_conf_showshare(struct net_context *c, werr = smbconf_get_share(conf_ctx, mem_ctx, sharename, &service); if (!W_ERROR_IS_OK(werr)) { d_printf("error getting share parameters: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -626,7 +626,7 @@ static int net_conf_addshare(struct net_context *c, werr = smbconf_create_share(conf_ctx, sharename); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error creating share %s: %s\n", - sharename, dos_errstr(werr)); + sharename, win_errstr(werr)); goto done; } @@ -637,7 +637,7 @@ static int net_conf_addshare(struct net_context *c, werr = smbconf_set_parameter(conf_ctx, sharename, "path", path); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", - "path", dos_errstr(werr)); + "path", win_errstr(werr)); goto done; } @@ -646,7 +646,7 @@ static int net_conf_addshare(struct net_context *c, comment); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", - "comment", dos_errstr(werr)); + "comment", win_errstr(werr)); goto done; } } @@ -654,7 +654,7 @@ static int net_conf_addshare(struct net_context *c, werr = smbconf_set_parameter(conf_ctx, sharename, "guest ok", guest_ok); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", - "'guest ok'", dos_errstr(werr)); + "'guest ok'", win_errstr(werr)); goto done; } @@ -662,7 +662,7 @@ static int net_conf_addshare(struct net_context *c, writeable); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting parameter %s: %s\n", - "writeable", dos_errstr(werr)); + "writeable", win_errstr(werr)); goto done; } @@ -695,7 +695,7 @@ static int net_conf_delshare(struct net_context *c, werr = smbconf_delete_share(conf_ctx, sharename); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error deleting share %s: %s\n", - sharename, dos_errstr(werr)); + sharename, win_errstr(werr)); goto done; } @@ -735,7 +735,7 @@ static int net_conf_setparm(struct net_context *c, struct smbconf_ctx *conf_ctx, werr = smbconf_create_share(conf_ctx, service); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error creating share '%s': %s\n", - service, dos_errstr(werr)); + service, win_errstr(werr)); goto done; } } @@ -744,7 +744,7 @@ static int net_conf_setparm(struct net_context *c, struct smbconf_ctx *conf_ctx, if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error setting value '%s': %s\n", - param, dos_errstr(werr)); + param, win_errstr(werr)); goto done; } @@ -796,7 +796,7 @@ static int net_conf_getparm(struct net_context *c, struct smbconf_ctx *conf_ctx, goto done; } else if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error getting value '%s': %s.\n", - param, dos_errstr(werr)); + param, win_errstr(werr)); goto done; } @@ -846,7 +846,7 @@ static int net_conf_delparm(struct net_context *c, struct smbconf_ctx *conf_ctx, goto done; } else if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "Error deleting value '%s': %s.\n", - param, dos_errstr(werr)); + param, win_errstr(werr)); goto done; } @@ -883,7 +883,7 @@ static int net_conf_getincludes(struct net_context *c, werr = smbconf_get_includes(conf_ctx, mem_ctx, service, &num_includes, &includes); if (!W_ERROR_IS_OK(werr)) { - d_printf("error getting includes: %s\n", dos_errstr(werr)); + d_printf("error getting includes: %s\n", win_errstr(werr)); goto done; } @@ -929,7 +929,7 @@ static int net_conf_setincludes(struct net_context *c, werr = smbconf_set_includes(conf_ctx, service, num_includes, includes); if (!W_ERROR_IS_OK(werr)) { - d_printf("error setting includes: %s\n", dos_errstr(werr)); + d_printf("error setting includes: %s\n", win_errstr(werr)); goto done; } @@ -962,7 +962,7 @@ static int net_conf_delincludes(struct net_context *c, werr = smbconf_delete_includes(conf_ctx, service); if (!W_ERROR_IS_OK(werr)) { - d_printf("error deleting includes: %s\n", dos_errstr(werr)); + d_printf("error deleting includes: %s\n", win_errstr(werr)); goto done; } diff --git a/source3/utils/net_dns.c b/source3/utils/net_dns.c index 4e617a1968..f4ad6f7b47 100644 --- a/source3/utils/net_dns.c +++ b/source3/utils/net_dns.c @@ -169,7 +169,7 @@ int get_my_ip_address( struct sockaddr_storage **pp_ss ) continue; /* Don't register loopback addresses */ - if (is_loopback_addr(nic_sa_storage)) { + if (is_loopback_addr((struct sockaddr *)nic_sa_storage)) { continue; } diff --git a/source3/utils/net_rap.c b/source3/utils/net_rap.c index 32f4dd31b4..570e951aee 100644 --- a/source3/utils/net_rap.c +++ b/source3/utils/net_rap.c @@ -1024,7 +1024,7 @@ int net_rap_groupmember_usage(struct net_context *c, int argc, const char **argv "net rap groupmember LIST <group> [misc. options] [targets]" "\n\t Enumerate users in a group\n" "\nnet rap groupmember DELETE <group> <user> [misc. options] " - "[targets]\n\t Delete sepcified user from specified group\n" + "[targets]\n\t Delete specified user from specified group\n" "\nnet rap groupmember ADD <group> <user> [misc. options] [targets]" "\n\t Add specified user to specified group\n"); diff --git a/source3/utils/net_registry.c b/source3/utils/net_registry.c index 26710b3580..64a0d8ac40 100644 --- a/source3/utils/net_registry.c +++ b/source3/utils/net_registry.c @@ -91,14 +91,14 @@ static WERROR open_key(TALLOC_CTX *ctx, const char *path, werr = open_hive(tmp_ctx, path, desired_access, &hive, &subkey_name); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_hive failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr)); goto done; } werr = reg_openkey(ctx, hive, subkey_name, desired_access, key); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_openkey failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -137,7 +137,7 @@ static int net_registry_enumerate(struct net_context *c, int argc, werr = open_key(ctx, argv[0], REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } @@ -193,7 +193,7 @@ static int net_registry_createkey(struct net_context *c, int argc, werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_hive failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr)); goto done; } @@ -201,7 +201,7 @@ static int net_registry_createkey(struct net_context *c, int argc, &subkey, &action); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_createkey failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } switch (action) { @@ -245,14 +245,14 @@ static int net_registry_deletekey(struct net_context *c, int argc, werr = open_hive(ctx, argv[0], REG_KEY_WRITE, &hivekey, &subkeyname); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_hive failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_hive failed: %s\n", win_errstr(werr)); goto done; } werr = reg_deletekey(hivekey, subkeyname); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_deletekey failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -280,14 +280,14 @@ static int net_registry_getvalue_internal(struct net_context *c, int argc, werr = open_key(ctx, argv[0], REG_KEY_READ, &key); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } werr = reg_queryvalue(ctx, key, argv[1], &value); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_queryvalue failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -346,14 +346,14 @@ static int net_registry_setvalue(struct net_context *c, int argc, werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } werr = reg_setvalue(key, argv[1], &value); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_setvalue failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -380,14 +380,14 @@ static int net_registry_deletevalue(struct net_context *c, int argc, werr = open_key(ctx, argv[0], REG_KEY_WRITE, &key); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } werr = reg_deletevalue(key, argv[1]); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_deletekey failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } @@ -429,14 +429,14 @@ static int net_registry_getsd(struct net_context *c, int argc, werr = open_key(ctx, argv[0], access_mask, &key); if (!W_ERROR_IS_OK(werr)) { - d_fprintf(stderr, "open_key failed: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "open_key failed: %s\n", win_errstr(werr)); goto done; } werr = reg_getkeysecurity(ctx, key, &secdesc); if (!W_ERROR_IS_OK(werr)) { d_fprintf(stderr, "reg_getkeysecurity failed: %s\n", - dos_errstr(werr)); + win_errstr(werr)); goto done; } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index ad22a55cdb..10f2a324a3 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -3133,7 +3133,7 @@ static NTSTATUS rpc_share_migrate_shares_internals(struct net_context *c, } if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result)) { - printf("cannot add share: %s\n", dos_errstr(result)); + printf("cannot add share: %s\n", win_errstr(result)); goto done; } @@ -3580,7 +3580,7 @@ static NTSTATUS rpc_share_migrate_security_internals(struct net_context *c, &parm_error, &result); if (!NT_STATUS_IS_OK(nt_status) || !W_ERROR_IS_OK(result)) { - printf("cannot set share-acl: %s\n", dos_errstr(result)); + printf("cannot set share-acl: %s\n", win_errstr(result)); goto done; } @@ -5075,7 +5075,7 @@ NTSTATUS rpc_reg_shutdown_internals(struct net_context *c, if ( W_ERROR_EQUAL(werr, WERR_MACHINE_LOCKED) ) d_fprintf(stderr, "\nMachine locked, use -f switch to force\n"); else - d_fprintf(stderr, "\nresult was: %s\n", dos_errstr(werr)); + d_fprintf(stderr, "\nresult was: %s\n", win_errstr(werr)); } return result; @@ -6113,7 +6113,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv) /* SamrConnect2 */ nt_status = rpccli_samr_Connect2(pipe_hnd, mem_ctx, pipe_hnd->desthost, - SA_RIGHT_SAM_OPEN_DOMAIN, + SAMR_ACCESS_OPEN_DOMAIN, &connect_hnd); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("Couldn't open SAMR policy handle. Error was %s\n", @@ -6127,7 +6127,7 @@ static int rpc_trustdom_list(struct net_context *c, int argc, const char **argv) able to enumerate accounts*/ nt_status = rpccli_samr_OpenDomain(pipe_hnd, mem_ctx, &connect_hnd, - SA_RIGHT_DOMAIN_ENUM_ACCOUNTS, + SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS, queried_dom_sid, &domain_hnd); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index ddd18a7b9f..c750e46b67 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -711,7 +711,7 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, level, num_printers, ctr); if (!W_ERROR_IS_OK(result)) { - printf("cannot enum printers: %s\n", dos_errstr(result)); + printf("cannot enum printers: %s\n", win_errstr(result)); return false; } @@ -752,7 +752,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, if (!W_ERROR_IS_OK(result)) { d_fprintf(stderr, "cannot open printer %s on server %s: %s\n", - printername2, servername, dos_errstr(result)); + printername2, servername, win_errstr(result)); return false; } @@ -774,7 +774,7 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_getprinter(pipe_hnd, mem_ctx, hnd, level, ctr); if (!W_ERROR_IS_OK(result)) { - printf("cannot get printer-info: %s\n", dos_errstr(result)); + printf("cannot get printer-info: %s\n", win_errstr(result)); return false; } @@ -793,7 +793,7 @@ static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, hnd, level, ctr, 0); if (!W_ERROR_IS_OK(result)) { - printf("cannot set printer-info: %s\n", dos_errstr(result)); + printf("cannot set printer-info: %s\n", win_errstr(result)); return false; } @@ -812,7 +812,7 @@ static bool net_spoolss_setprinterdata(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_setprinterdata(pipe_hnd, mem_ctx, hnd, value); if (!W_ERROR_IS_OK(result)) { - printf ("unable to set printerdata: %s\n", dos_errstr(result)); + printf ("unable to set printerdata: %s\n", win_errstr(result)); return false; } @@ -832,7 +832,7 @@ static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_enumprinterkey(pipe_hnd, mem_ctx, hnd, keyname, keylist, NULL); if (!W_ERROR_IS_OK(result)) { - printf("enumprinterkey failed: %s\n", dos_errstr(result)); + printf("enumprinterkey failed: %s\n", win_errstr(result)); return false; } @@ -852,7 +852,7 @@ static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_enumprinterdataex(pipe_hnd, mem_ctx, hnd, keyname, ctr); if (!W_ERROR_IS_OK(result)) { - printf("enumprinterdataex failed: %s\n", dos_errstr(result)); + printf("enumprinterdataex failed: %s\n", win_errstr(result)); return false; } @@ -873,7 +873,7 @@ static bool net_spoolss_setprinterdataex(struct rpc_pipe_client *pipe_hnd, keyname, value); if (!W_ERROR_IS_OK(result)) { - printf("could not set printerdataex: %s\n", dos_errstr(result)); + printf("could not set printerdataex: %s\n", win_errstr(result)); return false; } @@ -893,7 +893,7 @@ static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd, result = rpccli_spoolss_enumforms(pipe_hnd, mem_ctx, hnd, level, num_forms, forms); if (!W_ERROR_IS_OK(result)) { - printf("could not enum forms: %s\n", dos_errstr(result)); + printf("could not enum forms: %s\n", win_errstr(result)); return false; } @@ -914,7 +914,7 @@ static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, env, num_drivers, ctr); if (!W_ERROR_IS_OK(result)) { - printf("cannot enum drivers: %s\n", dos_errstr(result)); + printf("cannot enum drivers: %s\n", win_errstr(result)); return false; } @@ -936,10 +936,10 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, if (!W_ERROR_IS_OK(result)) { DEBUG(1,("cannot get driver (for architecture: %s): %s\n", - env, dos_errstr(result))); + env, win_errstr(result))); if (W_ERROR_V(result) != W_ERROR_V(WERR_UNKNOWN_PRINTER_DRIVER) && W_ERROR_V(result) != W_ERROR_V(WERR_INVALID_ENVIRONMENT)) { - printf("cannot get driver: %s\n", dos_errstr(result)); + printf("cannot get driver: %s\n", win_errstr(result)); } return false; } @@ -963,7 +963,7 @@ static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, return false; } if (!W_ERROR_IS_OK(result)) { - printf("cannot add driver: %s\n", dos_errstr(result)); + printf("cannot add driver: %s\n", win_errstr(result)); return false; } @@ -1231,7 +1231,7 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ result = rpccli_spoolss_setprinter(pipe_hnd, mem_ctx, &hnd, level, &ctr_pub, 0); if (!W_ERROR_IS_OK(result) && (W_ERROR_V(result) != W_ERROR_V(WERR_IO_PENDING))) { - printf("cannot set printer-info: %s\n", dos_errstr(result)); + printf("cannot set printer-info: %s\n", win_errstr(result)); goto done; } diff --git a/source3/utils/net_rpc_samsync.c b/source3/utils/net_rpc_samsync.c index c0922efe6b..73e6dd03cb 100644 --- a/source3/utils/net_rpc_samsync.c +++ b/source3/utils/net_rpc_samsync.c @@ -249,7 +249,10 @@ NTSTATUS rpc_vampire_keytab_internals(struct net_context *c, return status; } - if (argc >= 1) { + if (argc < 1) { + /* the caller should ensure that a filename is provided */ + return NT_STATUS_INVALID_PARAMETER; + } else { ctx->output_filename = argv[0]; } @@ -299,9 +302,13 @@ static NTSTATUS rpc_vampire_keytab_ds_internals(struct net_context *c, ctx->force_full_replication = c->opt_force_full_repl ? true : false; ctx->clean_old_entries = c->opt_clean_old_entries ? true : false; - if (argc >= 1) { + if (argc < 1) { + /* the caller should ensure that a filename is provided */ + return NT_STATUS_INVALID_PARAMETER; + } else { ctx->output_filename = argv[0]; } + if (argc >= 2) { ctx->object_dns = &argv[1]; ctx->object_count = argc - 1; @@ -342,9 +349,9 @@ int rpc_vampire_keytab(struct net_context *c, int argc, const char **argv) { int ret = 0; - if (c->display_usage) { + if (c->display_usage || (argc < 1)) { d_printf("Usage:\n" - "net rpc vampire keytab\n" + "net rpc vampire keytab <keytabfile>\n" " Dump remote SAM database to Kerberos keytab file\n"); return 0; } diff --git a/source3/utils/net_rpc_service.c b/source3/utils/net_rpc_service.c index 133173116c..7d1c4860aa 100644 --- a/source3/utils/net_rpc_service.c +++ b/source3/utils/net_rpc_service.c @@ -79,7 +79,7 @@ static WERROR query_service_state(struct rpc_pipe_client *pipe_hnd, &hService, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result)); return result; } @@ -158,7 +158,7 @@ static WERROR control_service(struct rpc_pipe_client *pipe_hnd, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result)); goto done; } @@ -171,7 +171,7 @@ static WERROR control_service(struct rpc_pipe_client *pipe_hnd, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Control service request failed. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Control service request failed. [%s]\n", win_errstr(result)); goto done; } @@ -220,7 +220,7 @@ static NTSTATUS rpc_service_list_internal(struct net_context *c, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result)); return werror_to_ntstatus(result); } @@ -228,7 +228,7 @@ static NTSTATUS rpc_service_list_internal(struct net_context *c, SVCCTL_STATE_ALL, &num_services, &services ); if ( !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Failed to enumerate services. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to enumerate services. [%s]\n", win_errstr(result)); goto done; } @@ -281,7 +281,7 @@ static NTSTATUS rpc_service_status_internal(struct net_context *c, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result)); return werror_to_ntstatus(result); } @@ -295,7 +295,7 @@ static NTSTATUS rpc_service_status_internal(struct net_context *c, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result)); goto done; } @@ -307,7 +307,7 @@ static NTSTATUS rpc_service_status_internal(struct net_context *c, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Query status request failed. [%s]\n", win_errstr(result)); goto done; } @@ -332,7 +332,7 @@ static NTSTATUS rpc_service_status_internal(struct net_context *c, } if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Query config request failed. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Query config request failed. [%s]\n", win_errstr(result)); goto done; } @@ -404,7 +404,7 @@ static NTSTATUS rpc_service_stop_internal(struct net_context *c, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result)); return werror_to_ntstatus(result); } @@ -448,7 +448,7 @@ static NTSTATUS rpc_service_pause_internal(struct net_context *c, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result)); return werror_to_ntstatus(result); } @@ -492,7 +492,7 @@ static NTSTATUS rpc_service_resume_internal(struct net_context *c, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result)); return werror_to_ntstatus(result); } @@ -534,7 +534,7 @@ static NTSTATUS rpc_service_start_internal(struct net_context *c, &hSCM, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result)) { - d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open Service Control Manager. [%s]\n", win_errstr(result)); return werror_to_ntstatus(result); } @@ -548,7 +548,7 @@ static NTSTATUS rpc_service_start_internal(struct net_context *c, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Failed to open service. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Failed to open service. [%s]\n", win_errstr(result)); goto done; } @@ -561,7 +561,7 @@ static NTSTATUS rpc_service_start_internal(struct net_context *c, &result); if (!NT_STATUS_IS_OK(status) || !W_ERROR_IS_OK(result) ) { - d_fprintf(stderr, "Query status request failed. [%s]\n", dos_errstr(result)); + d_fprintf(stderr, "Query status request failed. [%s]\n", win_errstr(result)); goto done; } @@ -570,7 +570,7 @@ static NTSTATUS rpc_service_start_internal(struct net_context *c, if ( W_ERROR_IS_OK(result) && (state == SVCCTL_RUNNING) ) d_printf("Successfully started service: %s\n", argv[0] ); else - d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], dos_errstr(result) ); + d_fprintf(stderr, "Failed to start service: %s [%s]\n", argv[0], win_errstr(result) ); done: rpccli_svcctl_CloseServiceHandle(pipe_hnd, mem_ctx, &hService, NULL); diff --git a/source3/utils/net_sam.c b/source3/utils/net_sam.c index ce132131f7..e8ebb60205 100644 --- a/source3/utils/net_sam.c +++ b/source3/utils/net_sam.c @@ -1735,7 +1735,7 @@ doma_done: d_printf("Checking Guest's group.\n"); - pwd = getpwnam_alloc(NULL, lp_guestaccount()); + pwd = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount()); if (!pwd) { d_fprintf(stderr, "Failed to find just created Guest account!\n" " Is nss properly configured?!\n"); diff --git a/source3/utils/ntlm_auth.c b/source3/utils/ntlm_auth.c index 0a76761cb2..fbb105bfe6 100644 --- a/source3/utils/ntlm_auth.c +++ b/source3/utils/ntlm_auth.c @@ -380,13 +380,25 @@ NTSTATUS contact_winbind_auth_crap(const char *username, } if (nt_response && nt_response->length) { - memcpy(request.data.auth_crap.nt_resp, - nt_response->data, - MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp))); + if (nt_response->length > sizeof(request.data.auth_crap.nt_resp)) { + request.flags = request.flags | WBFLAG_BIG_NTLMV2_BLOB; + request.extra_len = nt_response->length; + request.extra_data.data = SMB_MALLOC_ARRAY(char, request.extra_len); + if (request.extra_data.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + memcpy(request.extra_data.data, nt_response->data, + nt_response->length); + + } else { + memcpy(request.data.auth_crap.nt_resp, + nt_response->data, nt_response->length); + } request.data.auth_crap.nt_resp_len = nt_response->length; } result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response); + SAFE_FREE(request.extra_data.data); /* Display response */ diff --git a/source3/utils/pdbedit.c b/source3/utils/pdbedit.c index fe99b6fc9e..50cbc43d6d 100644 --- a/source3/utils/pdbedit.c +++ b/source3/utils/pdbedit.c @@ -571,7 +571,7 @@ static int new_user (struct pdb_methods *in, const char *username, get_global_sam_sid(); - if ( !(pwd = getpwnam_alloc( NULL, username )) ) { + if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), username )) ) { DEBUG(0,("Cannot locate Unix account for %s\n", username)); return -1; } @@ -675,7 +675,7 @@ static int new_machine (struct pdb_methods *in, const char *machine_in) fstrcpy(machineaccount, machinename); fstrcat(machineaccount, "$"); - if ( !(pwd = getpwnam_alloc( NULL, machineaccount )) ) { + if ( !(pwd = getpwnam_alloc(talloc_autofree_context(), machineaccount )) ) { DEBUG(0,("Cannot locate Unix account for %s\n", machineaccount)); return -1; } diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index 600fe52f0d..d2652ad95a 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -337,7 +337,7 @@ static int process_root(int local_flags) load_interfaces(); } - if (!user_name[0] && (pwd = getpwuid_alloc(NULL, geteuid()))) { + if (!user_name[0] && (pwd = getpwuid_alloc(talloc_autofree_context(), geteuid()))) { fstrcpy(user_name, pwd->pw_name); TALLOC_FREE(pwd); } @@ -498,7 +498,7 @@ static int process_nonroot(int local_flags) } if (!user_name[0]) { - pwd = getpwuid_alloc(NULL, getuid()); + pwd = getpwuid_alloc(talloc_autofree_context(), getuid()); if (pwd) { fstrcpy(user_name,pwd->pw_name); TALLOC_FREE(pwd); diff --git a/source3/web/cgi.c b/source3/web/cgi.c index ce36bd9310..49e83717c3 100644 --- a/source3/web/cgi.c +++ b/source3/web/cgi.c @@ -314,7 +314,7 @@ static void cgi_web_auth(void) exit(0); } - pwd = getpwnam_alloc(NULL, user); + pwd = getpwnam_alloc(talloc_autofree_context(), user); if (!pwd) { printf("%sCannot find user %s<br>%s\n", head, user, tail); exit(0); @@ -367,7 +367,7 @@ static bool cgi_handle_authorization(char *line) * Try and get the user from the UNIX password file. */ - pass = getpwnam_alloc(NULL, user); + pass = getpwnam_alloc(talloc_autofree_context(), user); /* * Validate the password they have given. diff --git a/source3/web/neg_lang.c b/source3/web/neg_lang.c index 82411000cd..491ca9eedd 100644 --- a/source3/web/neg_lang.c +++ b/source3/web/neg_lang.c @@ -74,7 +74,7 @@ void web_set_lang(const char *lang_string) int lang_num, i; /* build the lang list */ - lang_list = str_list_make(talloc_tos(), lang_string, ", \t\r\n"); + lang_list = str_list_make_v3(talloc_tos(), lang_string, ", \t\r\n"); if (!lang_list) return; /* sort the list by priority */ diff --git a/source3/winbindd/winbindd.c b/source3/winbindd/winbindd.c index ac2a87ffce..ce1a1fe52f 100644 --- a/source3/winbindd/winbindd.c +++ b/source3/winbindd/winbindd.c @@ -59,7 +59,7 @@ struct messaging_context *winbind_messaging_context(void) /* Reload configuration */ -static bool reload_services_file(const char *logfile) +static bool reload_services_file(const char *lfile) { bool ret; @@ -73,8 +73,8 @@ static bool reload_services_file(const char *logfile) /* if this is a child, restore the logfile to the special name - <domain>, idmap, etc. */ - if (logfile && *logfile) { - lp_set_logfile(logfile); + if (lfile && *lfile) { + lp_set_logfile(lfile); } reopen_logs(); @@ -792,14 +792,14 @@ static bool remove_idle_client(void) } /* check if HUP has been received and reload files */ -void winbind_check_sighup(const char *logfile) +void winbind_check_sighup(const char *lfile) { if (do_sighup) { DEBUG(3, ("got SIGHUP\n")); flush_caches(); - reload_services_file(logfile); + reload_services_file(lfile); do_sighup = False; } @@ -1096,11 +1096,11 @@ int main(int argc, char **argv, char **envp) poptFreeContext(pc); if (!override_logfile) { - char *logfile = NULL; - if (asprintf(&logfile,"%s/log.winbindd", + char *lfile = NULL; + if (asprintf(&lfile,"%s/log.winbindd", get_dyn_LOGFILEBASE()) > 0) { - lp_set_logfile(logfile); - SAFE_FREE(logfile); + lp_set_logfile(lfile); + SAFE_FREE(lfile); } } setup_logging("winbindd", log_stdout); diff --git a/source3/winbindd/winbindd_cm.c b/source3/winbindd/winbindd_cm.c index 9268542da6..3c69859731 100644 --- a/source3/winbindd/winbindd_cm.c +++ b/source3/winbindd/winbindd_cm.c @@ -225,10 +225,10 @@ static bool fork_child_dc_connect(struct winbindd_domain *domain) close_conns_after_fork(); if (!override_logfile) { - char *logfile; - if (asprintf(&logfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) > 0) { - lp_set_logfile(logfile); - SAFE_FREE(logfile); + char *lfile; + if (asprintf(&lfile, "%s/log.winbindd-dc-connect", get_dyn_LOGFILEBASE()) > 0) { + lp_set_logfile(lfile); + SAFE_FREE(lfile); reopen_logs(); } } @@ -672,7 +672,7 @@ static bool get_dc_name_via_netlogon(struct winbindd_domain *domain, if (!W_ERROR_IS_OK(werr)) { DEBUG(10,("rpccli_netr_GetAnyDCName failed: %s\n", - dos_errstr(werr))); + win_errstr(werr))); talloc_destroy(mem_ctx); return false; } diff --git a/source3/winbindd/winbindd_group.c b/source3/winbindd/winbindd_group.c index f2b6fbefb5..8e56138bb5 100644 --- a/source3/winbindd/winbindd_group.c +++ b/source3/winbindd/winbindd_group.c @@ -382,6 +382,24 @@ static int namecmp( const void *a, const void *b ) return StrCaseCmp( * (char * const *) a, * (char * const *) b); } +static void sort_unique_list(char ***list, uint32 *n_list) +{ + uint32_t i; + + /* search for duplicates for sorting and looking for matching + neighbors */ + + qsort(*list, *n_list, sizeof(char*), QSORT_CAST namecmp); + + for (i=1; i < *n_list; i++) { + if (strcmp((*list)[i-1], (*list)[i]) == 0) { + memmove(&((*list)[i-1]), &((*list)[i]), + sizeof(char*)*((*n_list)-i)); + (*n_list)--; + } + } +} + static NTSTATUS add_names_to_list( TALLOC_CTX *ctx, char ***list, uint32 *n_list, char **names, uint32 n_names ) @@ -414,19 +432,6 @@ static NTSTATUS add_names_to_list( TALLOC_CTX *ctx, new_list[i] = talloc_strdup( new_list, names[j] ); } - /* search for duplicates for sorting and looking for matching - neighbors */ - - qsort( new_list, n_new_list, sizeof(char*), QSORT_CAST namecmp ); - - for ( i=1; i<n_new_list; i++ ) { - if ( strcmp( new_list[i-1], new_list[i] ) == 0 ) { - memmove( &new_list[i-1], &new_list[i], - sizeof(char*)*(n_new_list-i) ); - n_new_list--; - } - } - *list = new_list; *n_list = n_new_list; @@ -663,6 +668,8 @@ static bool fill_grent_mem(struct winbindd_domain *domain, } TALLOC_FREE( glist ); + sort_unique_list(&names, &num_names); + DEBUG(10, ("looked up %d names\n", num_names)); again: diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index 50936c01a3..0e34615c3a 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -492,7 +492,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain, if (!W_ERROR_IS_OK(werr)) { DEBUG(5, ("Error requesting DCname for domain %s: %s\n", - state->request.domain_name, dos_errstr(werr))); + state->request.domain_name, win_errstr(werr))); return WINBINDD_ERROR; } diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 9ff3899661..7de28b08a9 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1854,17 +1854,28 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain, if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp) || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) { - DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", - state->request.data.auth_crap.lm_resp_len, - state->request.data.auth_crap.nt_resp_len)); - result = NT_STATUS_INVALID_PARAMETER; - goto done; + if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB || + state->request.extra_len != state->request.data.auth_crap.nt_resp_len) { + DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", + state->request.data.auth_crap.lm_resp_len, + state->request.data.auth_crap.nt_resp_len)); + result = NT_STATUS_INVALID_PARAMETER; + goto done; + } } lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp, state->request.data.auth_crap.lm_resp_len); - nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp, - state->request.data.auth_crap.nt_resp_len); + + if (state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) { + nt_resp = data_blob_talloc(state->mem_ctx, + state->request.extra_data.data, + state->request.data.auth_crap.nt_resp_len); + } else { + nt_resp = data_blob_talloc(state->mem_ctx, + state->request.data.auth_crap.nt_resp, + state->request.data.auth_crap.nt_resp_len); + } /* what domain should we contact? */ diff --git a/source3/winbindd/winbindd_proto.h b/source3/winbindd/winbindd_proto.h index 95ccf30cfe..65ad47dd03 100644 --- a/source3/winbindd/winbindd_proto.h +++ b/source3/winbindd/winbindd_proto.h @@ -63,7 +63,7 @@ void setup_async_write(struct fd_event *event, void *data, size_t length, void *private_data); void request_error(struct winbindd_cli_state *state); void request_ok(struct winbindd_cli_state *state); -void winbind_check_sighup(const char *logfile); +void winbind_check_sighup(const char *lfile); void winbind_check_sigterm(bool in_parent); int main(int argc, char **argv, char **envp); diff --git a/source3/winbindd/winbindd_rpc.c b/source3/winbindd/winbindd_rpc.c index d966e50159..7dea342a53 100644 --- a/source3/winbindd/winbindd_rpc.c +++ b/source3/winbindd/winbindd_rpc.c @@ -636,6 +636,8 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain, return NT_STATUS_OK; } +#define MAX_SAM_ENTRIES_W2K 0x400 /* 1024 */ + NTSTATUS msrpc_lookup_useraliases(struct winbindd_domain *domain, TALLOC_CTX *mem_ctx, uint32 num_sids, const DOM_SID *sids, diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index 5d57383d2a..7a8da71a7d 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -40,6 +40,12 @@ _PUBLIC_ struct gensec_security_ops **gensec_security_all(void) return generic_security_ops; } +bool gensec_security_ops_enabled(struct gensec_security_ops *ops, + struct loadparm_context *lp_ctx) +{ + return lp_parm_bool(lp_ctx, NULL, "gensec", ops->name, ops->enabled); +} + /* Sometimes we want to force only kerberos, sometimes we want to * force it's avoidance. The old list could be either * gensec_security_all(), or from cli_credentials_gensec_list() (ie, @@ -76,6 +82,7 @@ _PUBLIC_ struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ j = 0; for (i=0; old_gensec_list && old_gensec_list[i]; i++) { int oid_idx; + for (oid_idx = 0; old_gensec_list[i]->oid && old_gensec_list[i]->oid[oid_idx]; oid_idx++) { if (strcmp(old_gensec_list[i]->oid[oid_idx], GENSEC_OID_SPNEGO) == 0) { new_gensec_list[j] = old_gensec_list[i]; @@ -140,6 +147,9 @@ static const struct gensec_security_ops *gensec_security_by_authtype(struct gens } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { + if (!gensec_security_ops_enabled(backends[i], + gensec_security->settings->lp_ctx)) + continue; if (backends[i]->auth_type == auth_type) { backend = backends[i]; talloc_free(mem_ctx); @@ -163,6 +173,10 @@ const struct gensec_security_ops *gensec_security_by_oid(struct gensec_security } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { + if (gensec_security != NULL && + !gensec_security_ops_enabled(backends[i], + gensec_security->settings->lp_ctx)) + continue; if (backends[i]->oid) { for (j=0; backends[i]->oid[j]; j++) { if (backends[i]->oid[j] && @@ -191,6 +205,8 @@ const struct gensec_security_ops *gensec_security_by_sasl_name(struct gensec_sec } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { + if (!gensec_security_ops_enabled(backends[i], gensec_security->settings->lp_ctx)) + continue; if (backends[i]->sasl_name && (strcmp(backends[i]->sasl_name, sasl_name) == 0)) { backend = backends[i]; @@ -215,6 +231,9 @@ static const struct gensec_security_ops *gensec_security_by_name(struct gensec_s } backends = gensec_security_mechs(gensec_security, mem_ctx); for (i=0; backends && backends[i]; i++) { + if (gensec_security != NULL && + !gensec_security_ops_enabled(backends[i], gensec_security->settings->lp_ctx)) + continue; if (backends[i]->name && (strcmp(backends[i]->name, name) == 0)) { backend = backends[i]; @@ -258,6 +277,9 @@ const struct gensec_security_ops **gensec_security_by_sasl_list(struct gensec_se /* Find backends in our preferred order, by walking our list, * then looking in the supplied list */ for (i=0; backends && backends[i]; i++) { + if (gensec_security != NULL && + !gensec_security_ops_enabled(backends[i], gensec_security->settings->lp_ctx)) + continue; for (sasl_idx = 0; sasl_names[sasl_idx]; sasl_idx++) { if (!backends[i]->sasl_name || !(strcmp(backends[i]->sasl_name, @@ -326,6 +348,9 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gen /* Find backends in our preferred order, by walking our list, * then looking in the supplied list */ for (i=0; backends && backends[i]; i++) { + if (gensec_security != NULL && + !gensec_security_ops_enabled(backends[i], gensec_security->settings->lp_ctx)) + continue; if (!backends[i]->oid) { continue; } @@ -374,7 +399,8 @@ const struct gensec_security_ops_wrapper *gensec_security_by_oid_list(struct gen * Return OIDS from the security subsystems listed */ -const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx, +const char **gensec_security_oids_from_ops(struct gensec_security *gensec_security, + TALLOC_CTX *mem_ctx, struct gensec_security_ops **ops, const char *skip) { @@ -391,6 +417,10 @@ const char **gensec_security_oids_from_ops(TALLOC_CTX *mem_ctx, } for (i=0; ops && ops[i]; i++) { + if (gensec_security != NULL && + !gensec_security_ops_enabled(ops[i], gensec_security->settings->lp_ctx)) { + continue; + } if (!ops[i]->oid) { continue; } @@ -464,7 +494,7 @@ const char **gensec_security_oids(struct gensec_security *gensec_security, { struct gensec_security_ops **ops = gensec_security_mechs(gensec_security, mem_ctx); - return gensec_security_oids_from_ops(mem_ctx, ops, skip); + return gensec_security_oids_from_ops(gensec_security, mem_ctx, ops, skip); } @@ -477,7 +507,7 @@ const char **gensec_security_oids(struct gensec_security *gensec_security, */ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct loadparm_context *lp_ctx, + struct gensec_settings *settings, struct messaging_context *msg, struct gensec_security **gensec_security) { @@ -501,7 +531,8 @@ static NTSTATUS gensec_start(TALLOC_CTX *mem_ctx, (*gensec_security)->event_ctx = ev; (*gensec_security)->msg_ctx = msg; - (*gensec_security)->lp_ctx = lp_ctx; + SMB_ASSERT(settings->lp_ctx != NULL); + (*gensec_security)->settings = talloc_reference(*gensec_security, settings); return NT_STATUS_OK; } @@ -529,7 +560,7 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, (*gensec_security)->want_features = parent->want_features; (*gensec_security)->event_ctx = parent->event_ctx; (*gensec_security)->msg_ctx = parent->msg_ctx; - (*gensec_security)->lp_ctx = parent->lp_ctx; + (*gensec_security)->settings = talloc_reference(*gensec_security, parent->settings); return NT_STATUS_OK; } @@ -543,11 +574,16 @@ _PUBLIC_ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security, struct event_context *ev, - struct loadparm_context *lp_ctx) + struct gensec_settings *settings) { NTSTATUS status; - status = gensec_start(mem_ctx, ev, lp_ctx, NULL, gensec_security); + if (settings == NULL) { + DEBUG(0,("gensec_client_start: no settings given!\n")); + return NT_STATUS_INTERNAL_ERROR; + } + + status = gensec_start(mem_ctx, ev, settings, NULL, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -564,7 +600,7 @@ _PUBLIC_ NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, */ _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct loadparm_context *lp_ctx, + struct gensec_settings *settings, struct messaging_context *msg, struct gensec_security **gensec_security) { @@ -580,7 +616,12 @@ _PUBLIC_ NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, return NT_STATUS_INTERNAL_ERROR; } - status = gensec_start(mem_ctx, ev, lp_ctx, msg, gensec_security); + if (!settings) { + DEBUG(0,("gensec_server_start: no settings given!\n")); + return NT_STATUS_INTERNAL_ERROR; + } + + status = gensec_start(mem_ctx, ev, settings, msg, gensec_security); if (!NT_STATUS_IS_OK(status)) { return status; } @@ -653,10 +694,10 @@ _PUBLIC_ NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_s return gensec_start_mech(gensec_security); } -_PUBLIC_ const char *gensec_get_name_by_authtype(uint8_t authtype) +_PUBLIC_ const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, uint8_t authtype) { const struct gensec_security_ops *ops; - ops = gensec_security_by_authtype(NULL, authtype); + ops = gensec_security_by_authtype(gensec_security, authtype); if (ops) { return ops->name; } @@ -664,10 +705,11 @@ _PUBLIC_ const char *gensec_get_name_by_authtype(uint8_t authtype) } -_PUBLIC_ const char *gensec_get_name_by_oid(const char *oid_string) +_PUBLIC_ const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, + const char *oid_string) { const struct gensec_security_ops *ops; - ops = gensec_security_by_oid(NULL, oid_string); + ops = gensec_security_by_oid(gensec_security, oid_string); if (ops) { return ops->name; } @@ -697,6 +739,8 @@ NTSTATUS gensec_start_mech_by_ops(struct gensec_security *gensec_security, _PUBLIC_ NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid) { + SMB_ASSERT(gensec_security != NULL); + gensec_security->ops = gensec_security_by_oid(gensec_security, mech_oid); if (!gensec_security->ops) { DEBUG(3, ("Could not find GENSEC backend for oid=%s\n", mech_oid)); @@ -1107,9 +1151,8 @@ _PUBLIC_ NTSTATUS gensec_set_target_hostname(struct gensec_security *gensec_secu _PUBLIC_ const char *gensec_get_target_hostname(struct gensec_security *gensec_security) { /* We allow the target hostname to be overriden for testing purposes */ - const char *target_hostname = lp_parm_string(gensec_security->lp_ctx, NULL, "gensec", "target_hostname"); - if (target_hostname) { - return target_hostname; + if (gensec_security->settings->target_hostname) { + return gensec_security->settings->target_hostname; } if (gensec_security->target.hostname) { @@ -1205,11 +1248,6 @@ const char *gensec_get_target_principal(struct gensec_security *gensec_security) */ NTSTATUS gensec_register(const struct gensec_security_ops *ops) { - if (!lp_parm_bool(global_loadparm, NULL, "gensec", ops->name, ops->enabled)) { - DEBUG(2,("gensec subsystem %s is disabled\n", ops->name)); - return NT_STATUS_OK; - } - if (gensec_security_by_name(NULL, ops->name) != NULL) { /* its already registered! */ DEBUG(0,("GENSEC backend '%s' already registered\n", @@ -1255,6 +1293,16 @@ static int sort_gensec(struct gensec_security_ops **gs1, struct gensec_security_ return (*gs2)->priority - (*gs1)->priority; } +int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value) +{ + return lp_parm_int(settings->lp_ctx, NULL, mechanism, name, default_value); +} + +bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value) +{ + return lp_parm_bool(settings->lp_ctx, NULL, mechanism, name, default_value); +} + /* initialise the GENSEC subsystem */ diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 0b31882ddd..cb7f3aec99 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -64,6 +64,7 @@ enum gensec_role struct auth_session_info; struct cli_credentials; +struct gensec_settings; struct gensec_update_request { struct gensec_security *gensec_security; @@ -77,6 +78,12 @@ struct gensec_update_request { } callback; }; +struct gensec_settings { + struct loadparm_context *lp_ctx; + struct smb_iconv_convenience *iconv_convenience; + const char *target_hostname; +}; + struct gensec_security_ops { const char *name; const char *sasl_name; @@ -151,7 +158,6 @@ struct gensec_security_ops_wrapper { struct gensec_security { const struct gensec_security_ops *ops; - struct loadparm_context *lp_ctx; void *private_data; struct cli_credentials *credentials; struct gensec_target target; @@ -161,6 +167,7 @@ struct gensec_security { struct event_context *event_ctx; struct messaging_context *msg_ctx; /* only valid as server */ struct socket_address *my_addr, *peer_addr; + struct gensec_settings *settings; }; /* this structure is used by backends to determine the size of some critical types */ @@ -210,7 +217,7 @@ NTSTATUS gensec_subcontext_start(TALLOC_CTX *mem_ctx, NTSTATUS gensec_client_start(TALLOC_CTX *mem_ctx, struct gensec_security **gensec_security, struct event_context *ev, - struct loadparm_context *lp_ctx); + struct gensec_settings *settings); NTSTATUS gensec_start_mech_by_sasl_list(struct gensec_security *gensec_security, const char **sasl_names); NTSTATUS gensec_update(struct gensec_security *gensec_security, TALLOC_CTX *out_mem_ctx, @@ -232,7 +239,7 @@ NTSTATUS gensec_session_key(struct gensec_security *gensec_security, DATA_BLOB *session_key); NTSTATUS gensec_start_mech_by_oid(struct gensec_security *gensec_security, const char *mech_oid); -const char *gensec_get_name_by_oid(const char *oid_string); +const char *gensec_get_name_by_oid(struct gensec_security *gensec_security, const char *oid_string); struct cli_credentials *gensec_get_credentials(struct gensec_security *gensec_security); struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security); NTSTATUS gensec_init(struct loadparm_context *lp_ctx); @@ -259,10 +266,10 @@ NTSTATUS gensec_sign_packet(struct gensec_security *gensec_security, DATA_BLOB *sig); NTSTATUS gensec_start_mech_by_authtype(struct gensec_security *gensec_security, uint8_t auth_type, uint8_t auth_level); -const char *gensec_get_name_by_authtype(uint8_t authtype); +const char *gensec_get_name_by_authtype(struct gensec_security *gensec_security, uint8_t authtype); NTSTATUS gensec_server_start(TALLOC_CTX *mem_ctx, struct event_context *ev, - struct loadparm_context *lp_ctx, + struct gensec_settings *settings, struct messaging_context *msg, struct gensec_security **gensec_security); NTSTATUS gensec_session_info(struct gensec_security *gensec_security, @@ -288,6 +295,7 @@ NTSTATUS gensec_wrap(struct gensec_security *gensec_security, DATA_BLOB *out); struct gensec_security_ops **gensec_security_all(void); +bool gensec_security_ops_enabled(struct gensec_security_ops *ops, struct loadparm_context *lp_ctx); struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx, struct gensec_security_ops **old_gensec_list, struct cli_credentials *creds); @@ -295,5 +303,7 @@ struct gensec_security_ops **gensec_use_kerberos_mechs(TALLOC_CTX *mem_ctx, NTSTATUS gensec_start_mech_by_sasl_name(struct gensec_security *gensec_security, const char *sasl_name); +int gensec_setting_int(struct gensec_settings *settings, const char *mechanism, const char *name, int default_value); +bool gensec_setting_bool(struct gensec_settings *settings, const char *mechanism, const char *name, bool default_value); #endif /* __GENSEC_H__ */ diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c index e307dbb5cb..dcfffef3df 100644 --- a/source4/auth/gensec/gensec_gssapi.c +++ b/source4/auth/gensec/gensec_gssapi.c @@ -154,7 +154,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->gss_exchange_count = 0; gensec_gssapi_state->max_wrap_buf_size - = lp_parm_int(gensec_security->lp_ctx, NULL, "gensec_gssapi", "max wrap buf size", 65536); + = gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536); gensec_gssapi_state->sasl = false; gensec_gssapi_state->sasl_state = STAGE_GSS_NEG; @@ -170,16 +170,16 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS; gensec_gssapi_state->want_flags = 0; - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "mutual", true)) { + if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) { gensec_gssapi_state->want_flags |= GSS_C_MUTUAL_FLAG; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "delegation", true)) { + if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation", true)) { gensec_gssapi_state->want_flags |= GSS_C_DELEG_FLAG; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "replay", true)) { + if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "replay", true)) { gensec_gssapi_state->want_flags |= GSS_C_REPLAY_FLAG; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "sequence", true)) { + if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "sequence", true)) { gensec_gssapi_state->want_flags |= GSS_C_SEQUENCE_FLAG; } @@ -214,10 +214,10 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) talloc_free(gensec_gssapi_state); return NT_STATUS_INTERNAL_ERROR; } - if (lp_realm(gensec_security->lp_ctx) && *lp_realm(gensec_security->lp_ctx)) { - char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->lp_ctx)); + if (lp_realm(gensec_security->settings->lp_ctx) && *lp_realm(gensec_security->settings->lp_ctx)) { + char *upper_realm = strupper_talloc(gensec_gssapi_state, lp_realm(gensec_security->settings->lp_ctx)); if (!upper_realm) { - DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->lp_ctx))); + DEBUG(1,("gensec_krb5_start: could not uppercase realm: %s\n", lp_realm(gensec_security->settings->lp_ctx))); talloc_free(gensec_gssapi_state); return NT_STATUS_NO_MEMORY; } @@ -231,7 +231,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) } /* don't do DNS lookups of any kind, it might/will fail for a netbios name */ - ret = gsskrb5_set_dns_canonicalize(lp_parm_bool(gensec_security->lp_ctx, NULL, "krb5", "set_dns_canonicalize", false)); + ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false)); if (ret) { DEBUG(1,("gensec_krb5_start: gsskrb5_set_dns_canonicalize failed\n")); talloc_free(gensec_gssapi_state); @@ -240,7 +240,7 @@ static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security) ret = smb_krb5_init_context(gensec_gssapi_state, gensec_security->event_ctx, - gensec_security->lp_ctx, + gensec_security->settings->lp_ctx, &gensec_gssapi_state->smb_krb5_context); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n", @@ -274,7 +274,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi } else { ret = cli_credentials_get_server_gss_creds(machine_account, gensec_security->event_ctx, - gensec_security->lp_ctx, &gcc); + gensec_security->settings->lp_ctx, &gcc); if (ret) { DEBUG(1, ("Aquiring acceptor credentials failed: %s\n", error_message(ret))); @@ -336,7 +336,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi gensec_gssapi_state->gss_oid = gss_mech_krb5; principal = gensec_get_target_principal(gensec_security); - if (principal && lp_client_use_spnego_principal(gensec_security->lp_ctx)) { + if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) { name_type = GSS_C_NULL_OID; } else { principal = talloc_asprintf(gensec_gssapi_state, "%s@%s", @@ -362,7 +362,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi ret = cli_credentials_get_client_gss_creds(creds, gensec_security->event_ctx, - gensec_security->lp_ctx, &gcc); + gensec_security->settings->lp_ctx, &gcc); switch (ret) { case 0: break; @@ -1142,10 +1142,10 @@ static bool gensec_gssapi_have_feature(struct gensec_security *gensec_security, return false; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "force_new_spnego", false)) { + if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "force_new_spnego", false)) { return true; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec_gssapi", "disable_new_spnego", false)) { + if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "disable_new_spnego", false)) { return false; } @@ -1256,7 +1256,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi */ if (pac_blob.length) { nt_status = kerberos_pac_blob_to_server_info(mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), + gensec_security->settings->iconv_convenience, pac_blob, gensec_gssapi_state->smb_krb5_context->krb5_context, &server_info); @@ -1290,11 +1290,11 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_NO_MEMORY; } - if (!lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec", "require_pac", false)) { + if (!gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC, resorting to local user lookup: %s\n", gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, - gensec_security->lp_ctx, principal_string, + gensec_security->settings->lp_ctx, principal_string, &server_info); if (!NT_STATUS_IS_OK(nt_status)) { @@ -1311,7 +1311,7 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi /* references the server_info into the session_info */ nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, - gensec_security->lp_ctx, server_info, &session_info); + gensec_security->settings->lp_ctx, server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); return nt_status; @@ -1334,13 +1334,13 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi return NT_STATUS_NO_MEMORY; } - cli_credentials_set_conf(session_info->credentials, gensec_security->lp_ctx); + cli_credentials_set_conf(session_info->credentials, gensec_security->settings->lp_ctx); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(session_info->credentials); ret = cli_credentials_set_client_gss_creds(session_info->credentials, gensec_security->event_ctx, - gensec_security->lp_ctx, + gensec_security->settings->lp_ctx, gensec_gssapi_state->delegated_cred_handle, CRED_SPECIFIED); if (ret) { diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 1f54043038..16867366a4 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -120,7 +120,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) if (cli_credentials_get_krb5_context(creds, gensec_security->event_ctx, - gensec_security->lp_ctx, &gensec_krb5_state->smb_krb5_context)) { + gensec_security->settings->lp_ctx, &gensec_krb5_state->smb_krb5_context)) { talloc_free(gensec_krb5_state); return NT_STATUS_INTERNAL_ERROR; } @@ -252,7 +252,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security ret = cli_credentials_get_ccache(gensec_get_credentials(gensec_security), gensec_security->event_ctx, - gensec_security->lp_ctx, &ccache_container); + gensec_security->settings->lp_ctx, &ccache_container); switch (ret) { case 0: break; @@ -267,7 +267,7 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security } in_data.length = 0; - if (principal && lp_client_use_spnego_principal(gensec_security->lp_ctx)) { + if (principal && lp_client_use_spnego_principal(gensec_security->settings->lp_ctx)) { krb5_principal target_principal; ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal, &target_principal); @@ -452,7 +452,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, /* Grab the keytab, however generated */ ret = cli_credentials_get_keytab(gensec_get_credentials(gensec_security), gensec_security->event_ctx, - gensec_security->lp_ctx, &keytab); + gensec_security->settings->lp_ctx, &keytab); if (ret) { return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; } @@ -594,7 +594,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security KRB5_AUTHDATA_WIN2K_PAC, &pac_data); - if (ret && lp_parm_bool(gensec_security->lp_ctx, NULL, "gensec", "require_pac", false)) { + if (ret && gensec_setting_bool(gensec_security->settings, "gensec", "require_pac", false)) { DEBUG(1, ("Unable to find PAC in ticket from %s, failing to allow access: %s \n", principal_string, smb_get_krb5_error_message(context, @@ -607,7 +607,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", smb_get_krb5_error_message(context, ret, mem_ctx))); - nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, gensec_security->lp_ctx, principal_string, + nt_status = sam_get_server_info_principal(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, principal_string, &server_info); krb5_free_principal(context, client_principal); free(principal_string); @@ -630,7 +630,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security /* decode and verify the pac */ nt_status = kerberos_pac_logon_info(gensec_krb5_state, - lp_iconv_convenience(gensec_security->lp_ctx), + gensec_security->settings->iconv_convenience, &logon_info, pac, gensec_krb5_state->smb_krb5_context->krb5_context, NULL, gensec_krb5_state->keyblock, @@ -655,7 +655,7 @@ static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security } /* references the server_info into the session_info */ - nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->lp_ctx, server_info, &session_info); + nt_status = auth_generate_session_info(mem_ctx, gensec_security->event_ctx, gensec_security->settings->lp_ctx, server_info, &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(mem_ctx); diff --git a/source4/auth/gensec/schannel.c b/source4/auth/gensec/schannel.c index f21202b86f..e6d38c14a3 100644 --- a/source4/auth/gensec/schannel.c +++ b/source4/auth/gensec/schannel.c @@ -85,7 +85,7 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ #endif ndr_err = ndr_push_struct_blob(out, out_mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), &bind_schannel, + gensec_security->settings->iconv_convenience, &bind_schannel, (ndr_push_flags_fn_t)ndr_push_schannel_bind); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -106,7 +106,7 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ /* parse the schannel startup blob */ ndr_err = ndr_pull_struct_blob(&in, out_mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), + gensec_security->settings->iconv_convenience, &bind_schannel, (ndr_pull_flags_fn_t)ndr_pull_schannel_bind); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { @@ -126,7 +126,7 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ /* pull the session key for this client */ status = schannel_fetch_session_key(out_mem_ctx, gensec_security->event_ctx, - gensec_security->lp_ctx, workstation, + gensec_security->settings->lp_ctx, workstation, domain, &creds); if (!NT_STATUS_IS_OK(status)) { DEBUG(3, ("Could not find session key for attempted schannel connection from %s: %s\n", @@ -144,7 +144,7 @@ static NTSTATUS schannel_update(struct gensec_security *gensec_security, TALLOC_ bind_schannel_ack.unknown3 = 0x6c0000; ndr_err = ndr_push_struct_blob(out, out_mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), &bind_schannel_ack, + gensec_security->settings->iconv_convenience, &bind_schannel_ack, (ndr_push_flags_fn_t)ndr_push_schannel_bind_ack); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); @@ -190,7 +190,7 @@ static NTSTATUS schannel_session_info(struct gensec_security *gensec_security, struct auth_session_info **_session_info) { struct schannel_state *state = talloc_get_type(gensec_security->private_data, struct schannel_state); - return auth_anonymous_session_info(state, gensec_security->event_ctx, gensec_security->lp_ctx, _session_info); + return auth_anonymous_session_info(state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, _session_info); } static NTSTATUS schannel_start(struct gensec_security *gensec_security) diff --git a/source4/auth/gensec/spnego.c b/source4/auth/gensec/spnego.c index bf991616bd..e51b215807 100644 --- a/source4/auth/gensec/spnego.c +++ b/source4/auth/gensec/spnego.c @@ -336,6 +336,11 @@ static NTSTATUS gensec_spnego_server_try_fallback(struct gensec_security *gensec for (i=0; all_ops[i]; i++) { bool is_spnego; NTSTATUS nt_status; + + if (gensec_security != NULL && + !gensec_security_ops_enabled(all_ops[i], gensec_security->settings->lp_ctx)) + continue; + if (!all_ops[i]->oid) { continue; } @@ -969,8 +974,8 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA spnego.negTokenTarg.supportedMech && strcmp(spnego.negTokenTarg.supportedMech, spnego_state->neg_oid) != 0) { DEBUG(3,("GENSEC SPNEGO: client preferred mech (%s) not accepted, server wants: %s\n", - gensec_get_name_by_oid(spnego.negTokenTarg.supportedMech), - gensec_get_name_by_oid(spnego_state->neg_oid))); + gensec_get_name_by_oid(gensec_security, spnego.negTokenTarg.supportedMech), + gensec_get_name_by_oid(gensec_security, spnego_state->neg_oid))); talloc_free(spnego_state->sub_sec_security); nt_status = gensec_subcontext_start(spnego_state, diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c index 90b542c4c4..06db904130 100644 --- a/source4/auth/kerberos/krb5_init_context.c +++ b/source4/auth/kerberos/krb5_init_context.c @@ -250,14 +250,10 @@ krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, status = NT_STATUS_INVALID_PARAMETER; switch (hi->proto) { case KRB5_KRBHST_UDP: - if (lp_parm_bool(global_loadparm, NULL, "krb5", "udp", true)) { - status = socket_create(name, SOCKET_TYPE_DGRAM, &smb_krb5->sock, 0); - } + status = socket_create(name, SOCKET_TYPE_DGRAM, &smb_krb5->sock, 0); break; case KRB5_KRBHST_TCP: - if (lp_parm_bool(global_loadparm, NULL, "krb5", "tcp", true)) { - status = socket_create(name, SOCKET_TYPE_STREAM, &smb_krb5->sock, 0); - } + status = socket_create(name, SOCKET_TYPE_STREAM, &smb_krb5->sock, 0); break; case KRB5_KRBHST_HTTP: talloc_free(smb_krb5); diff --git a/source4/auth/ntlm/auth_sam.c b/source4/auth/ntlm/auth_sam.c index 78429106f6..d1be5b6e30 100644 --- a/source4/auth/ntlm/auth_sam.c +++ b/source4/auth/ntlm/auth_sam.c @@ -185,7 +185,7 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context, *lm_sess_key = data_blob(NULL, 0); *user_sess_key = data_blob(NULL, 0); status = hash_password_check(mem_ctx, - auth_context->lp_ctx, + lp_lanman_auth(auth_context->lp_ctx), user_info->password.hash.lanman, user_info->password.hash.nt, user_info->mapped.account_name, @@ -195,7 +195,8 @@ static NTSTATUS authsam_password_ok(struct auth_context *auth_context, case AUTH_PASSWORD_RESPONSE: status = ntlm_password_check(mem_ctx, - auth_context->lp_ctx, + lp_lanman_auth(auth_context->lp_ctx), + lp_ntlm_auth(auth_context->lp_ctx), user_info->logon_parameters, &auth_context->challenge.data, &user_info->password.response.lanman, diff --git a/source4/auth/ntlm/auth_server.c b/source4/auth/ntlm/auth_server.c index 0b1e091eea..fd0ef0fe4a 100644 --- a/source4/auth/ntlm/auth_server.c +++ b/source4/auth/ntlm/auth_server.c @@ -66,6 +66,8 @@ static NTSTATUS server_get_challenge(struct auth_method_context *ctx, TALLOC_CTX return NT_STATUS_INTERNAL_ERROR; } io.in.dest_ports = lp_smb_ports(ctx->auth_ctx->lp_ctx); + io.in.socket_options = lp_socket_options(ctx->auth_ctx->lp_ctx); + io.in.gensec_settings = lp_gensec_settings(mem_ctx, ctx->auth_ctx->lp_ctx); io.in.called_name = strupper_talloc(mem_ctx, io.in.dest_host); @@ -145,6 +147,7 @@ static NTSTATUS server_check_password(struct auth_method_context *ctx, session_setup.in.credentials = creds; session_setup.in.workgroup = ""; /* Only used with SPNEGO, which we are not doing */ + session_setup.in.gensec_settings = lp_gensec_settings(session, ctx->auth_ctx->lp_ctx); /* Check password with remove server - this should be async some day */ nt_status = smb_composite_sesssetup(session, &session_setup); diff --git a/source4/auth/ntlm/ntlm_check.c b/source4/auth/ntlm/ntlm_check.c index b43190c5ba..a3ac7f3347 100644 --- a/source4/auth/ntlm/ntlm_check.c +++ b/source4/auth/ntlm/ntlm_check.c @@ -23,7 +23,6 @@ #include "../lib/crypto/crypto.h" #include "librpc/gen_ndr/netlogon.h" #include "libcli/auth/libcli_auth.h" -#include "param/param.h" #include "auth/ntlm/ntlm_check.h" /**************************************************************************** @@ -220,7 +219,7 @@ static bool smb_sess_key_ntlmv2(TALLOC_CTX *mem_ctx, */ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx, + bool lanman_auth, const struct samr_Password *client_lanman, const struct samr_Password *client_nt, const char *username, @@ -242,7 +241,7 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, } } else if (client_lanman && stored_lanman) { - if (!lp_lanman_auth(lp_ctx)) { + if (!lanman_auth) { DEBUG(3,("ntlm_password_check: Interactive logon: only LANMAN password supplied for user %s, and LM passwords are disabled!\n", username)); return NT_STATUS_WRONG_PASSWORD; @@ -283,7 +282,8 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, */ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx, + bool lanman_auth, + bool ntlm_auth, uint32_t logon_parameters, const DATA_BLOB *challenge, const DATA_BLOB *lm_response, @@ -321,7 +321,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, mdfour(client_nt.hash, nt_response->data, nt_response->length); if (lm_response->length && - (convert_string_talloc_convenience(mem_ctx, lp_iconv_convenience(lp_ctx), CH_DOS, CH_UNIX, + (convert_string_talloc(mem_ctx, CH_DOS, CH_UNIX, lm_response->data, lm_response->length, (void **)&unix_pw) != -1)) { if (E_deshash(unix_pw, client_lm.hash)) { @@ -333,7 +333,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, lm_ok = false; } return hash_password_check(mem_ctx, - lp_ctx, + lanman_auth, lm_ok ? &client_lm : NULL, nt_response->length ? &client_nt : NULL, username, @@ -396,7 +396,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, DEBUG(3,("ntlm_password_check: NTLMv2 password check failed\n")); } } else if (nt_response->length == 24 && stored_nt) { - if (lp_ntlm_auth(lp_ctx)) { + if (ntlm_auth) { /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). */ @@ -408,7 +408,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, /* The LM session key for this response is not very secure, so use it only if we otherwise allow LM authentication */ - if (lp_lanman_auth(lp_ctx) && stored_lanman) { + if (lanman_auth && stored_lanman) { *lm_sess_key = data_blob_talloc(mem_ctx, stored_lanman->hash, 8); } return NT_STATUS_OK; @@ -436,7 +436,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, return NT_STATUS_WRONG_PASSWORD; } - if (!lp_lanman_auth(lp_ctx)) { + if (!lanman_auth) { DEBUG(3,("ntlm_password_check: Lanman passwords NOT PERMITTED for user %s\n", username)); } else if (!stored_lanman) { @@ -455,7 +455,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, It not very secure, so use it only if we otherwise allow LM authentication */ - if (lp_lanman_auth(lp_ctx) && stored_lanman) { + if (lanman_auth && stored_lanman) { uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, stored_lanman->hash, 8); memset(first_8_lm_hash + 8, '\0', 8); @@ -571,7 +571,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - I think this is related to Win9X pass-though authentication */ DEBUG(4,("ntlm_password_check: Checking NT MD4 password in LM field\n")); - if (lp_ntlm_auth(lp_ctx)) { + if (ntlm_auth) { if (smb_pwd_check_ntlmv1(mem_ctx, lm_response, stored_nt->hash, challenge, @@ -580,7 +580,7 @@ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, It not very secure, so use it only if we otherwise allow LM authentication */ - if (lp_lanman_auth(lp_ctx) && stored_lanman) { + if (lanman_auth && stored_lanman) { uint8_t first_8_lm_hash[16]; memcpy(first_8_lm_hash, stored_lanman->hash, 8); memset(first_8_lm_hash + 8, '\0', 8); diff --git a/source4/auth/ntlm/ntlm_check.h b/source4/auth/ntlm/ntlm_check.h index eb115b74d6..df11f7d7a2 100644 --- a/source4/auth/ntlm/ntlm_check.h +++ b/source4/auth/ntlm/ntlm_check.h @@ -36,7 +36,7 @@ */ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx, + bool lanman_auth, const struct samr_Password *client_lanman, const struct samr_Password *client_nt, const char *username, @@ -61,7 +61,8 @@ NTSTATUS hash_password_check(TALLOC_CTX *mem_ctx, */ NTSTATUS ntlm_password_check(TALLOC_CTX *mem_ctx, - struct loadparm_context *lp_ctx, + bool lanman_auth, + bool ntlm_auth, uint32_t logon_parameters, const DATA_BLOB *challenge, const DATA_BLOB *lm_response, diff --git a/source4/auth/ntlmssp/ntlmssp.c b/source4/auth/ntlmssp/ntlmssp.c index cea18c45a7..1b14e461c3 100644 --- a/source4/auth/ntlmssp/ntlmssp.c +++ b/source4/auth/ntlmssp/ntlmssp.c @@ -159,7 +159,6 @@ static NTSTATUS gensec_ntlmssp_update_find(struct gensec_ntlmssp_state *gensec_n } } else { if (!msrpc_parse(gensec_ntlmssp_state, - lp_iconv_convenience(gensec_security->lp_ctx), &input, "Cd", "NTLMSSP", &ntlmssp_command)) { diff --git a/source4/auth/ntlmssp/ntlmssp_client.c b/source4/auth/ntlmssp/ntlmssp_client.c index 0ef40200fe..e28d8462d4 100644 --- a/source4/auth/ntlmssp/ntlmssp_client.c +++ b/source4/auth/ntlmssp/ntlmssp_client.c @@ -122,7 +122,6 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if (!msrpc_parse(mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), &in, "CdBd", "NTLMSSP", &ntlmssp_command, @@ -160,7 +159,6 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if (!msrpc_parse(mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), &in, chal_parse_string, "NTLMSSP", &ntlmssp_command, @@ -194,7 +192,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, if (gensec_ntlmssp_state->use_nt_response) { flags |= CLI_CRED_NTLM_AUTH; } - if (lp_client_lanman_auth(gensec_security->lp_ctx)) { + if (lp_client_lanman_auth(gensec_security->settings->lp_ctx)) { flags |= CLI_CRED_LANMAN_AUTH; } @@ -219,7 +217,7 @@ NTSTATUS ntlmssp_client_challenge(struct gensec_security *gensec_security, } if ((gensec_ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - && lp_client_lanman_auth(gensec_security->lp_ctx) && lm_session_key.length == 16) { + && lp_client_lanman_auth(gensec_security->settings->lp_ctx) && lm_session_key.length == 16) { DATA_BLOB new_session_key = data_blob_talloc(mem_ctx, NULL, 16); if (lm_response.length == 24) { SMBsesskeygen_lm_sess_key(lm_session_key.data, lm_response.data, @@ -310,17 +308,17 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->role = NTLMSSP_CLIENT; - gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->lp_ctx); + gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx); - gensec_ntlmssp_state->unicode = lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "unicode", true); + gensec_ntlmssp_state->unicode = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "unicode", true); - gensec_ntlmssp_state->use_nt_response = lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "send_nt_reponse", true); + gensec_ntlmssp_state->use_nt_response = gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "send_nt_reponse", true); - gensec_ntlmssp_state->allow_lm_key = (lp_client_lanman_auth(gensec_security->lp_ctx) - && (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "allow_lm_key", false) - || lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "lm_key", false))); + gensec_ntlmssp_state->allow_lm_key = (lp_client_lanman_auth(gensec_security->settings->lp_ctx) + && (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "allow_lm_key", false) + || gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false))); - gensec_ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(gensec_security->lp_ctx); + gensec_ntlmssp_state->use_ntlmv2 = lp_client_ntlmv2_auth(gensec_security->settings->lp_ctx); gensec_ntlmssp_state->expected_state = NTLMSSP_INITIAL; @@ -328,27 +326,27 @@ NTSTATUS gensec_ntlmssp_client_start(struct gensec_security *gensec_security) NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_REQUEST_TARGET; - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "128bit", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "128bit", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "56bit", false)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "56bit", false)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "lm_key", false)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "lm_key", false)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_LM_KEY; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "keyexchange", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "keyexchange", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "alwayssign", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "alwayssign", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_client", "ntlm2", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_client", "ntlm2", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } else { /* apparently we can't do ntlmv2 if we don't do ntlm2 */ diff --git a/source4/auth/ntlmssp/ntlmssp_parse.c b/source4/auth/ntlmssp/ntlmssp_parse.c index 24f3ad27af..d606b8d563 100644 --- a/source4/auth/ntlmssp/ntlmssp_parse.c +++ b/source4/auth/ntlmssp/ntlmssp_parse.c @@ -186,7 +186,7 @@ if ((head_ofs + amount) > blob->length) { \ return false; \ } -/* +/** this is a tiny msrpc packet parser. This the the partner of msrpc_gen format specifiers are: @@ -200,7 +200,6 @@ if ((head_ofs + amount) > blob->length) { \ */ bool msrpc_parse(TALLOC_CTX *mem_ctx, - struct smb_iconv_convenience *iconv_convenience, const DATA_BLOB *blob, const char *format, ...) { diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index 38973f623d..37cc5f318f 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -136,7 +136,6 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security, if (in.length) { if ((in.length < 16) || !msrpc_parse(out_mem_ctx, - lp_iconv_convenience(gensec_security->lp_ctx), &in, "Cdd", "NTLMSSP", &ntlmssp_command, @@ -187,7 +186,7 @@ NTSTATUS ntlmssp_server_negotiate(struct gensec_security *gensec_security, /* Find out the DNS domain name */ dnsdomname[0] = '\0'; - safe_strcpy(dnsdomname, lp_realm(gensec_security->lp_ctx), sizeof(dnsdomname) - 1); + safe_strcpy(dnsdomname, lp_realm(gensec_security->settings->lp_ctx), sizeof(dnsdomname) - 1); strlower_m(dnsdomname); /* Find out the DNS host name */ @@ -282,7 +281,6 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlms /* now the NTLMSSP encoded auth hashes */ if (!msrpc_parse(gensec_ntlmssp_state, - lp_iconv_convenience(gensec_ntlmssp_state->gensec_security->lp_ctx), &request, parse_string, "NTLMSSP", &ntlmssp_command, @@ -309,7 +307,6 @@ static NTSTATUS ntlmssp_server_preauth(struct gensec_ntlmssp_state *gensec_ntlms /* now the NTLMSSP encoded auth hashes */ if (!msrpc_parse(gensec_ntlmssp_state, - lp_iconv_convenience(gensec_ntlmssp_state->gensec_security->lp_ctx), &request, parse_string, "NTLMSSP", &ntlmssp_command, @@ -725,7 +722,7 @@ NTSTATUS gensec_ntlmssp_session_info(struct gensec_security *gensec_security, NTSTATUS nt_status; struct gensec_ntlmssp_state *gensec_ntlmssp_state = (struct gensec_ntlmssp_state *)gensec_security->private_data; - nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->lp_ctx, gensec_ntlmssp_state->server_info, session_info); + nt_status = auth_generate_session_info(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->settings->lp_ctx, gensec_ntlmssp_state->server_info, session_info); NT_STATUS_NOT_OK_RETURN(nt_status); (*session_info)->session_key = data_blob_talloc(*session_info, @@ -752,14 +749,14 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->role = NTLMSSP_SERVER; gensec_ntlmssp_state->workstation = NULL; - gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->lp_ctx); + gensec_ntlmssp_state->server_name = lp_netbios_name(gensec_security->settings->lp_ctx); - gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->lp_ctx); + gensec_ntlmssp_state->domain = lp_workgroup(gensec_security->settings->lp_ctx); gensec_ntlmssp_state->expected_state = NTLMSSP_NEGOTIATE; - gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->lp_ctx) - && lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_server", "allow_lm_key", false)); + gensec_ntlmssp_state->allow_lm_key = (lp_lanman_auth(gensec_security->settings->lp_ctx) + && gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "allow_lm_key", false)); gensec_ntlmssp_state->server_multiple_authentications = false; @@ -770,23 +767,23 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->nt_resp = data_blob(NULL, 0); gensec_ntlmssp_state->encrypted_session_key = data_blob(NULL, 0); - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_server", "128bit", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "128bit", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_128; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_server", "56bit", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "56bit", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_56; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_server", "keyexchange", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "keyexchange", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_KEY_EXCH; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_server", "alwayssign", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "alwayssign", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; } - if (lp_parm_bool(gensec_security->lp_ctx, NULL, "ntlmssp_server", "ntlm2", true)) { + if (gensec_setting_bool(gensec_security->settings, "ntlmssp_server", "ntlm2", true)) { gensec_ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_NTLM2; } @@ -800,7 +797,7 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) nt_status = auth_context_create(gensec_ntlmssp_state, gensec_security->event_ctx, gensec_security->msg_ctx, - gensec_security->lp_ctx, + gensec_security->settings->lp_ctx, &gensec_ntlmssp_state->auth_context); NT_STATUS_NOT_OK_RETURN(nt_status); @@ -808,7 +805,7 @@ NTSTATUS gensec_ntlmssp_server_start(struct gensec_security *gensec_security) gensec_ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge; gensec_ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge; gensec_ntlmssp_state->check_password = auth_ntlmssp_check_password; - gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->lp_ctx); + gensec_ntlmssp_state->server_role = lp_server_role(gensec_security->settings->lp_ctx); return NT_STATUS_OK; } diff --git a/source4/auth/sam.c b/source4/auth/sam.c index 4255a6432a..f6a998ae0f 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -447,7 +447,8 @@ NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - sam_ctx = samdb_connect(tmp_ctx, event_ctx, lp_ctx, system_session(tmp_ctx, lp_ctx)); + sam_ctx = samdb_connect(tmp_ctx, event_ctx, lp_ctx, + system_session(tmp_ctx, lp_ctx)); if (sam_ctx == NULL) { talloc_free(tmp_ctx); return NT_STATUS_INVALID_SYSTEM_SERVICE; @@ -459,7 +460,8 @@ NTSTATUS sam_get_server_info_principal(TALLOC_CTX *mem_ctx, return nt_status; } - nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, lp_netbios_name(lp_ctx), + nt_status = authsam_make_server_info(tmp_ctx, sam_ctx, + lp_netbios_name(lp_ctx), msgs[0], msgs_domain_ref[0], user_sess_key, lm_sess_key, server_info); diff --git a/source4/auth/system_session.c b/source4/auth/system_session.c index 1d227fe468..07b0060643 100644 --- a/source4/auth/system_session.c +++ b/source4/auth/system_session.c @@ -234,6 +234,7 @@ NTSTATUS auth_system_server_info(TALLOC_CTX *mem_ctx, const char *netbios_name, struct auth_serversupplied_info **_server_info) { struct auth_serversupplied_info *server_info; + server_info = talloc(mem_ctx, struct auth_serversupplied_info); NT_STATUS_HAVE_NO_MEMORY(server_info); diff --git a/source4/client/cifsdd.c b/source4/client/cifsdd.c index 6d35dc6b82..8d0b87d722 100644 --- a/source4/client/cifsdd.c +++ b/source4/client/cifsdd.c @@ -358,8 +358,10 @@ static struct dd_iohandle * open_file(struct resolve_context *resolve_ctx, struct event_context *ev, const char * which, const char **ports, struct smbcli_options *smb_options, + const char *socket_options, struct smbcli_session_options *smb_session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { int options = 0; const char * path = NULL; @@ -381,15 +383,19 @@ static struct dd_iohandle * open_file(struct resolve_context *resolve_ctx, path = check_arg_pathname("if"); handle = dd_open_path(resolve_ctx, ev, path, ports, check_arg_numeric("ibs"), options, + socket_options, smb_options, smb_session_options, - iconv_convenience); + iconv_convenience, + gensec_settings); } else if (strcmp(which, "of") == 0) { options |= DD_WRITE; path = check_arg_pathname("of"); handle = dd_open_path(resolve_ctx, ev, path, ports, check_arg_numeric("obs"), options, + socket_options, smb_options, smb_session_options, - iconv_convenience); + iconv_convenience, + gensec_settings); } else { SMB_ASSERT(0); return(NULL); @@ -443,14 +449,18 @@ static int copy_files(struct event_context *ev, struct loadparm_context *lp_ctx) if (!(ifile = open_file(lp_resolve_context(lp_ctx), ev, "if", lp_smb_ports(lp_ctx), &options, - &session_options, lp_iconv_convenience(lp_ctx)))) { + lp_socket_options(lp_ctx), + &session_options, lp_iconv_convenience(lp_ctx), + lp_gensec_settings(lp_ctx, lp_ctx)))) { return(FILESYS_EXIT_CODE); } if (!(ofile = open_file(lp_resolve_context(lp_ctx), ev, "of", lp_smb_ports(lp_ctx), &options, + lp_socket_options(lp_ctx), &session_options, - lp_iconv_convenience(lp_ctx)))) { + lp_iconv_convenience(lp_ctx), + lp_gensec_settings(lp_ctx, lp_ctx)))) { return(FILESYS_EXIT_CODE); } diff --git a/source4/client/cifsdd.h b/source4/client/cifsdd.h index bb851fa248..28fe6778f4 100644 --- a/source4/client/cifsdd.h +++ b/source4/client/cifsdd.h @@ -97,9 +97,11 @@ struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, const char * path, const char **ports, uint64_t io_size, int options, + const char *socket_options, struct smbcli_options *smb_options, struct smbcli_session_options *smb_session_options, - struct smb_iconv_convenience *iconv_convenience); + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings); bool dd_fill_block(struct dd_iohandle * h, uint8_t * buf, uint64_t * buf_size, uint64_t need_size, uint64_t block_size); bool dd_flush_block(struct dd_iohandle * h, uint8_t * buf, diff --git a/source4/client/cifsddio.c b/source4/client/cifsddio.c index 3c9e0c2202..06631ee3ac 100644 --- a/source4/client/cifsddio.c +++ b/source4/client/cifsddio.c @@ -225,9 +225,11 @@ static struct smbcli_state * init_smb_session(struct resolve_context *resolve_ct const char * host, const char **ports, const char * share, + const char *socket_options, struct smbcli_options *options, struct smbcli_session_options *session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { NTSTATUS ret; struct smbcli_state * cli = NULL; @@ -237,10 +239,12 @@ static struct smbcli_state * init_smb_session(struct resolve_context *resolve_ct */ ret = smbcli_full_connection(NULL, &cli, host, ports, share, NULL /* devtype */, + socket_options, cmdline_credentials, resolve_ctx, ev, options, session_options, - iconv_convenience); + iconv_convenience, + gensec_settings); if (!NT_STATUS_IS_OK(ret)) { fprintf(stderr, "%s: connecting to //%s/%s: %s\n", @@ -306,9 +310,11 @@ static struct dd_iohandle * open_cifs_handle(struct resolve_context *resolve_ctx const char * path, uint64_t io_size, int options, + const char *socket_options, struct smbcli_options *smb_options, struct smbcli_session_options *smb_session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { struct cifs_handle * smbh; @@ -329,8 +335,10 @@ static struct dd_iohandle * open_cifs_handle(struct resolve_context *resolve_ctx smbh->h.io_seek = smb_seek_func; if ((smbh->cli = init_smb_session(resolve_ctx, ev, host, ports, share, + socket_options, smb_options, smb_session_options, - iconv_convenience)) == NULL) { + iconv_convenience, + gensec_settings)) == NULL) { return(NULL); } @@ -351,9 +359,11 @@ struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, const char **ports, uint64_t io_size, int options, + const char *socket_options, struct smbcli_options *smb_options, struct smbcli_session_options *smb_session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { if (file_exist(path)) { return(open_fd_handle(path, io_size, options)); @@ -370,9 +380,11 @@ struct dd_iohandle * dd_open_path(struct resolve_context *resolve_ctx, return(open_cifs_handle(resolve_ctx, ev, host, ports, share, remain, - io_size, options, smb_options, + io_size, options, + socket_options, smb_options, smb_session_options, - iconv_convenience)); + iconv_convenience, + gensec_settings)); } return(open_fd_handle(path, io_size, options)); diff --git a/source4/client/client.c b/source4/client/client.c index 7eb14a2ce1..a600b5fb0c 100644 --- a/source4/client/client.c +++ b/source4/client/client.c @@ -52,6 +52,7 @@ #include "librpc/gen_ndr/ndr_nbt.h" #include "param/param.h" #include "librpc/rpc/dcerpc.h" +#include "libcli/raw/raw_proto.h" /* the default pager to use for the client "more" command. Users can * override this with the PAGER environment variable */ @@ -3044,10 +3045,12 @@ static bool do_connect(struct smbclient_context *ctx, struct resolve_context *resolve_ctx, const char *specified_server, const char **ports, const char *specified_share, + const char *socket_options, struct cli_credentials *cred, struct smbcli_options *options, struct smbcli_session_options *session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { NTSTATUS status; char *server, *share; @@ -3065,9 +3068,12 @@ static bool do_connect(struct smbclient_context *ctx, ctx->remote_cur_dir = talloc_strdup(ctx, "\\"); status = smbcli_full_connection(ctx, &ctx->cli, server, ports, - share, NULL, cred, resolve_ctx, + share, NULL, + socket_options, + cred, resolve_ctx, ev_ctx, options, session_options, - iconv_convenience); + iconv_convenience, + gensec_settings); if (!NT_STATUS_IS_OK(status)) { d_printf("Connection to \\\\%s\\%s failed - %s\n", server, share, nt_errstr(status)); @@ -3101,7 +3107,8 @@ static int do_message_op(const char *netbios_name, const char *desthost, struct event_context *ev_ctx, struct resolve_context *resolve_ctx, struct smbcli_options *options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + const char *socket_options) { struct nbt_name called, calling; const char *server_name; @@ -3116,7 +3123,8 @@ static int do_message_op(const char *netbios_name, const char *desthost, if (!(cli = smbcli_state_init(NULL)) || !smbcli_socket_connect(cli, server_name, destports, ev_ctx, resolve_ctx, options, - iconv_convenience)) { + iconv_convenience, + socket_options)) { d_printf("Connection to %s failed\n", server_name); return 1; } @@ -3269,14 +3277,17 @@ static int do_message_op(const char *netbios_name, const char *desthost, lp_smb_ports(cmdline_lp_ctx), dest_ip, name_type, ev_ctx, lp_resolve_context(cmdline_lp_ctx), - &smb_options, lp_iconv_convenience(cmdline_lp_ctx)); + &smb_options, lp_iconv_convenience(cmdline_lp_ctx), + lp_socket_options(cmdline_lp_ctx)); return rc; } if (!do_connect(ctx, ev_ctx, lp_resolve_context(cmdline_lp_ctx), desthost, lp_smb_ports(cmdline_lp_ctx), service, + lp_socket_options(cmdline_lp_ctx), cmdline_credentials, &smb_options, &smb_session_options, - lp_iconv_convenience(cmdline_lp_ctx))) + lp_iconv_convenience(cmdline_lp_ctx), + lp_gensec_settings(ctx, cmdline_lp_ctx))) return 1; if (base_directory) diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 69e456274c..2161286e08 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -657,6 +657,28 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct return acct_flags; } +struct lsa_BinaryString samdb_result_parameters(TALLOC_CTX *mem_ctx, + struct ldb_message *msg, + const char *attr) +{ + struct lsa_BinaryString s; + const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr); + + ZERO_STRUCT(s); + + if (!val) { + return s; + } + + s.array = talloc_array(mem_ctx, uint16_t, val->length/2); + if (!s.array) { + return s; + } + s.length = s.size = val->length/2; + memcpy(s.array, val->data, val->length); + + return s; +} /* Find an attribute, with a particular value */ @@ -897,6 +919,17 @@ int samdb_msg_add_logon_hours(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, } /* + add a parameters element to a message +*/ +int samdb_msg_add_parameters(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, + const char *attr_name, struct lsa_BinaryString *parameters) +{ + struct ldb_val val; + val.length = parameters->length * 2; + val.data = (uint8_t *)parameters->array; + return ldb_msg_add_value(msg, attr_name, &val, NULL); +} +/* add a general value element to a message */ int samdb_msg_add_value(struct ldb_context *sam_ldb, TALLOC_CTX *mem_ctx, struct ldb_message *msg, diff --git a/source4/dsdb/samdb/ldb_modules/linked_attributes.c b/source4/dsdb/samdb/ldb_modules/linked_attributes.c index 190a66cdb3..dd199c0137 100644 --- a/source4/dsdb/samdb/ldb_modules/linked_attributes.c +++ b/source4/dsdb/samdb/ldb_modules/linked_attributes.c @@ -79,15 +79,17 @@ static struct la_context *linked_attributes_init(struct ldb_module *module, /* Common routine to handle reading the attributes and creating a * series of modify requests */ static int la_store_op(struct la_context *ac, - enum la_op op, char *dn, + enum la_op op, struct ldb_val *dn, const char *name, const char *value) { struct la_op_store *os, *tmp; struct ldb_dn *op_dn; - op_dn = ldb_dn_new(ac, ac->module->ldb, dn); + op_dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, dn); if (!op_dn) { - return LDB_ERR_OPERATIONS_ERROR; + ldb_asprintf_errstring(ac->module->ldb, + "could not parse attribute as a DN"); + return LDB_ERR_INVALID_DN_SYNTAX; } /* optimize out del - add operations that would end up @@ -177,7 +179,7 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request * int ret; int i, j; - if (ldb_dn_is_special(req->op.mod.message->dn)) { + if (ldb_dn_is_special(req->op.add.message->dn)) { /* do not manipulate our control entries */ return ldb_next_request(module, req); } @@ -233,7 +235,7 @@ static int linked_attributes_add(struct ldb_module *module, struct ldb_request * for (j = 0; j < el->num_values; j++) { ret = la_store_op(ac, LA_OP_ADD, - (char *)el->values[j].data, + &el->values[j], attr_name, attr_val); if (ret != LDB_SUCCESS) { return ret; @@ -327,7 +329,7 @@ static int la_mod_search_callback(struct ldb_request *req, struct ldb_reply *are /* make sure we manage each value */ for (j = 0; j < search_el->num_values; j++) { ret = la_store_op(ac, LA_OP_DEL, - (char *)search_el->values[j].data, + &search_el->values[j], attr_name, dn); if (ret != LDB_SUCCESS) { talloc_free(ares); @@ -445,7 +447,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques /* For each value being added, we need to setup the adds */ for (j = 0; j < el->num_values; j++) { ret = la_store_op(ac, LA_OP_ADD, - (char *)el->values[j].data, + &el->values[j], attr_name, attr_val); if (ret != LDB_SUCCESS) { return ret; @@ -459,7 +461,7 @@ static int linked_attributes_modify(struct ldb_module *module, struct ldb_reques /* For each value being deleted, we need to setup the delete */ for (j = 0; j < el->num_values; j++) { ret = la_store_op(ac, LA_OP_DEL, - (char *)el->values[j].data, + &el->values[j], attr_name, attr_val); if (ret != LDB_SUCCESS) { return ret; @@ -701,7 +703,7 @@ static int la_op_search_callback(struct ldb_request *req, } for (j = 0; j < el->num_values; j++) { ret = la_store_op(ac, LA_OP_DEL, - (char *)el->values[j].data, + &el->values[j], attr_name, deldn); if (ret != LDB_SUCCESS) { talloc_free(ares); @@ -710,7 +712,7 @@ static int la_op_search_callback(struct ldb_request *req, } if (!adddn) continue; ret = la_store_op(ac, LA_OP_ADD, - (char *)el->values[j].data, + &el->values[j], attr_name, adddn); if (ret != LDB_SUCCESS) { talloc_free(ares); diff --git a/source4/dsdb/samdb/ldb_modules/normalise.c b/source4/dsdb/samdb/ldb_modules/normalise.c index 70513bd644..2366bc7856 100644 --- a/source4/dsdb/samdb/ldb_modules/normalise.c +++ b/source4/dsdb/samdb/ldb_modules/normalise.c @@ -120,7 +120,7 @@ static int normalize_search_callback(struct ldb_request *req, struct ldb_reply * } for (j = 0; j < msg->elements[i].num_values; j++) { const char *dn_str; - struct ldb_dn *dn = ldb_dn_new(ac, ac->module->ldb, (const char *)msg->elements[i].values[j].data); + struct ldb_dn *dn = ldb_dn_from_ldb_val(ac, ac->module->ldb, &msg->elements[i].values[j]); if (!dn) { return ldb_module_done(ac->req, NULL, NULL, LDB_ERR_OPERATIONS_ERROR); } diff --git a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py index 1fc531902d..7162edcb3d 100644 --- a/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py +++ b/source4/dsdb/samdb/ldb_modules/tests/samba3sam.py @@ -27,7 +27,7 @@ import ldb from ldb import SCOPE_DEFAULT, SCOPE_BASE, SCOPE_SUBTREE from samba import Ldb, substitute_var from samba.tests import LdbTestCase, TestCaseInTempDir, cmdline_loadparm -import samba.dcerpc.security +import samba.dcerpc.dom_sid import samba.security import samba.ndr @@ -116,7 +116,7 @@ class MapBaseTestCase(TestCaseInTempDir): super(MapBaseTestCase, self).tearDown() def assertSidEquals(self, text, ndr_sid): - sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.security.dom_sid, + sid_obj1 = samba.ndr.ndr_unpack(samba.dcerpc.dom_sid.dom_sid, str(ndr_sid[0])) sid_obj2 = samba.security.Sid(text) # For now, this is the only way we can compare these since the diff --git a/source4/dsdb/schema/schema_syntax.c b/source4/dsdb/schema/schema_syntax.c index e0e6b3fc77..cee74c0593 100644 --- a/source4/dsdb/schema/schema_syntax.c +++ b/source4/dsdb/schema/schema_syntax.c @@ -1322,9 +1322,6 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .attributeSyntax_oid = "2.5.5.14", .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb, .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi, - .equality = "distinguishedNameMatch", - .comment = "OctetString: String+DN", - .ldb_syntax = LDB_SYNTAX_DN, },{ /* not used in w2k3 schema */ .name = "Object(DN-String)", @@ -1334,6 +1331,8 @@ static const struct dsdb_syntax dsdb_syntaxes[] = { .attributeSyntax_oid = "2.5.5.14", .drsuapi_to_ldb = dsdb_syntax_FOOBAR_drsuapi_to_ldb, .ldb_to_drsuapi = dsdb_syntax_FOOBAR_ldb_to_drsuapi, + .equality = "distinguishedNameMatch", + .comment = "OctetString: String+DN", .ldb_syntax = LDB_SYNTAX_DN, } }; diff --git a/source4/headermap.txt b/source4/headermap.txt index 4574a66a7b..cb5a4fab4c 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -6,6 +6,8 @@ ../lib/util/attr.h: util/attr.h ../lib/util/byteorder.h: util/byteorder.h ../lib/util/safe_string.h: util/safe_string.h +../lib/util/memory.h: util/memory.h +../lib/util/talloc_stack.h: util/talloc_stack.h ../lib/util/xfile.h: util/xfile.h lib/tdr/tdr.h: tdr.h librpc/rpc/dcerpc.h: dcerpc.h @@ -13,10 +15,14 @@ lib/ldb/include/ldb.h: ldb.h lib/ldb/include/ldb_errors.h: ldb_errors.h auth/gensec/gensec.h: gensec.h ../librpc/ndr/libndr.h: ndr.h +librpc/ndr/libndr.h: ndr.h lib/registry/registry.h: registry.h ../libcli/util/werror.h: core/werror.h ../libcli/util/doserr.h: core/doserr.h ../libcli/util/ntstatus.h: core/ntstatus.h +libcli/util/werror.h: core/werror.h +libcli/util/doserr.h: core/doserr.h +libcli/util/ntstatus.h: core/ntstatus.h libcli/cldap/cldap.h: cldap.h librpc/gen_ndr/dcerpc.h: gen_ndr/dcerpc.h librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h @@ -73,3 +79,4 @@ libcli/ldap/ldap_ndr.h: ldap_ndr.h lib/events/events.h: events.h lib/events/events_internal.h: events_internal.h auth/session.h: samba/session.h +../talloc/talloc.h: talloc.h diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index b986279ad4..4cf93e5a54 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -1376,6 +1376,7 @@ tgs_build_reply(krb5_context context, krb5_realm ref_realm = NULL; EncTicketPart *tgt = &ticket->ticket; KRB5SignedPathPrincipals *spp = NULL; + Key *tkey; const EncryptionKey *ekey; krb5_keyblock sessionkey; krb5_kvno kvno; @@ -1627,27 +1628,24 @@ server_lookup: goto out; } - /* check PAC if not cross realm and if there is one */ - if (!cross_realm) { - Key *tkey; + /* check PAC if there is one */ - ret = hdb_enctype2key(context, &krbtgt->entry, - krbtgt_etype, &tkey); - if(ret) { - kdc_log(context, config, 0, - "Failed to find key for krbtgt PAC check"); - goto out; - } + ret = hdb_enctype2key(context, &krbtgt->entry, + krbtgt_etype, &tkey); + if(ret) { + kdc_log(context, config, 0, + "Failed to find key for krbtgt PAC check"); + goto out; + } - ret = check_PAC(context, config, cp, - client, server, ekey, &tkey->key, - tgt, &rspac, &signedpath); - if (ret) { - kdc_log(context, config, 0, - "Verify PAC failed for %s (%s) from %s with %s", - spn, cpn, from, krb5_get_err_text(context, ret)); - goto out; - } + ret = check_PAC(context, config, cp, + client, server, ekey, &tkey->key, + tgt, &rspac, &signedpath); + if (ret) { + kdc_log(context, config, 0, + "Verify PAC failed for %s (%s) from %s with %s", + spn, cpn, from, krb5_get_err_text(context, ret)); + goto out; } /* also check the krbtgt for signature */ diff --git a/source4/heimdal/lib/krb5/get_addrs.c b/source4/heimdal/lib/krb5/get_addrs.c new file mode 100644 index 0000000000..fb45d08d29 --- /dev/null +++ b/source4/heimdal/lib/krb5/get_addrs.c @@ -0,0 +1,292 @@ +/* + * Copyright (c) 1997 - 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "krb5_locl.h" + +RCSID("$Id: get_addrs.c 23815 2008-09-13 09:21:03Z lha $"); + +#ifdef __osf__ +/* hate */ +struct rtentry; +struct mbuf; +#endif +#ifdef HAVE_NET_IF_H +#include <net/if.h> +#endif +#include <ifaddrs.h> + +static krb5_error_code +gethostname_fallback (krb5_context context, krb5_addresses *res) +{ + krb5_error_code ret; + char hostname[MAXHOSTNAMELEN]; + struct hostent *hostent; + + if (gethostname (hostname, sizeof(hostname))) { + ret = errno; + krb5_set_error_message(context, ret, "gethostname: %s", strerror(ret)); + return ret; + } + hostent = roken_gethostbyname (hostname); + if (hostent == NULL) { + ret = errno; + krb5_set_error_message (context, ret, "gethostbyname %s: %s", + hostname, strerror(ret)); + return ret; + } + res->len = 1; + res->val = malloc (sizeof(*res->val)); + if (res->val == NULL) { + krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); + return ENOMEM; + } + res->val[0].addr_type = hostent->h_addrtype; + res->val[0].address.data = NULL; + res->val[0].address.length = 0; + ret = krb5_data_copy (&res->val[0].address, + hostent->h_addr, + hostent->h_length); + if (ret) { + free (res->val); + return ret; + } + return 0; +} + +enum { + LOOP = 1, /* do include loopback interfaces */ + LOOP_IF_NONE = 2, /* include loopback if no other if's */ + EXTRA_ADDRESSES = 4, /* include extra addresses */ + SCAN_INTERFACES = 8 /* scan interfaces for addresses */ +}; + +/* + * Try to figure out the addresses of all configured interfaces with a + * lot of magic ioctls. + */ + +static krb5_error_code +find_all_addresses (krb5_context context, krb5_addresses *res, int flags) +{ + struct sockaddr sa_zero; + struct ifaddrs *ifa0, *ifa; + krb5_error_code ret = ENXIO; + unsigned int num, idx; + krb5_addresses ignore_addresses; + + res->val = NULL; + + if (getifaddrs(&ifa0) == -1) { + ret = errno; + krb5_set_error_message(context, ret, "getifaddrs: %s", strerror(ret)); + return (ret); + } + + memset(&sa_zero, 0, sizeof(sa_zero)); + + /* First, count all the ifaddrs. */ + for (ifa = ifa0, num = 0; ifa != NULL; ifa = ifa->ifa_next, num++) + /* nothing */; + + if (num == 0) { + freeifaddrs(ifa0); + krb5_set_error_message(context, ENXIO, N_("no addresses found", "")); + return (ENXIO); + } + + if (flags & EXTRA_ADDRESSES) { + /* we'll remove the addresses we don't care about */ + ret = krb5_get_ignore_addresses(context, &ignore_addresses); + if(ret) + return ret; + } + + /* Allocate storage for them. */ + res->val = calloc(num, sizeof(*res->val)); + if (res->val == NULL) { + krb5_free_addresses(context, &ignore_addresses); + freeifaddrs(ifa0); + krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); + return ENOMEM; + } + + /* Now traverse the list. */ + for (ifa = ifa0, idx = 0; ifa != NULL; ifa = ifa->ifa_next) { + if ((ifa->ifa_flags & IFF_UP) == 0) + continue; + if (ifa->ifa_addr == NULL) + continue; + if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0) + continue; + if (krb5_sockaddr_uninteresting(ifa->ifa_addr)) + continue; + if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) { + /* We'll deal with the LOOP_IF_NONE case later. */ + if ((flags & LOOP) == 0) + continue; + } + + ret = krb5_sockaddr2address(context, ifa->ifa_addr, &res->val[idx]); + if (ret) { + /* + * The most likely error here is going to be "Program + * lacks support for address type". This is no big + * deal -- just continue, and we'll listen on the + * addresses who's type we *do* support. + */ + continue; + } + /* possibly skip this address? */ + if((flags & EXTRA_ADDRESSES) && + krb5_address_search(context, &res->val[idx], &ignore_addresses)) { + krb5_free_address(context, &res->val[idx]); + flags &= ~LOOP_IF_NONE; /* we actually found an address, + so don't add any loop-back + addresses */ + continue; + } + + idx++; + } + + /* + * If no addresses were found, and LOOP_IF_NONE is set, then find + * the loopback addresses and add them to our list. + */ + if ((flags & LOOP_IF_NONE) != 0 && idx == 0) { + for (ifa = ifa0; ifa != NULL; ifa = ifa->ifa_next) { + if ((ifa->ifa_flags & IFF_UP) == 0) + continue; + if (ifa->ifa_addr == NULL) + continue; + if (memcmp(ifa->ifa_addr, &sa_zero, sizeof(sa_zero)) == 0) + continue; + if (krb5_sockaddr_uninteresting(ifa->ifa_addr)) + continue; + + if ((ifa->ifa_flags & IFF_LOOPBACK) != 0) { + ret = krb5_sockaddr2address(context, + ifa->ifa_addr, &res->val[idx]); + if (ret) { + /* + * See comment above. + */ + continue; + } + if((flags & EXTRA_ADDRESSES) && + krb5_address_search(context, &res->val[idx], + &ignore_addresses)) { + krb5_free_address(context, &res->val[idx]); + continue; + } + idx++; + } + } + } + + if (flags & EXTRA_ADDRESSES) + krb5_free_addresses(context, &ignore_addresses); + freeifaddrs(ifa0); + if (ret) { + free(res->val); + res->val = NULL; + } else + res->len = idx; /* Now a count. */ + return (ret); +} + +static krb5_error_code +get_addrs_int (krb5_context context, krb5_addresses *res, int flags) +{ + krb5_error_code ret = -1; + + if (flags & SCAN_INTERFACES) { + ret = find_all_addresses (context, res, flags); + if(ret || res->len == 0) + ret = gethostname_fallback (context, res); + } else { + res->len = 0; + res->val = NULL; + ret = 0; + } + + if(ret == 0 && (flags & EXTRA_ADDRESSES)) { + krb5_addresses a; + /* append user specified addresses */ + ret = krb5_get_extra_addresses(context, &a); + if(ret) { + krb5_free_addresses(context, res); + return ret; + } + ret = krb5_append_addresses(context, res, &a); + if(ret) { + krb5_free_addresses(context, res); + return ret; + } + krb5_free_addresses(context, &a); + } + if(res->len == 0) { + free(res->val); + res->val = NULL; + } + return ret; +} + +/* + * Try to get all addresses, but return the one corresponding to + * `hostname' if we fail. + * + * Only include loopback address if there are no other. + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_all_client_addrs (krb5_context context, krb5_addresses *res) +{ + int flags = LOOP_IF_NONE | EXTRA_ADDRESSES; + + if (context->scan_interfaces) + flags |= SCAN_INTERFACES; + + return get_addrs_int (context, res, flags); +} + +/* + * Try to get all local addresses that a server should listen to. + * If that fails, we return the address corresponding to `hostname'. + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_all_server_addrs (krb5_context context, krb5_addresses *res) +{ + return get_addrs_int (context, res, LOOP | SCAN_INTERFACES); +} diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index 85ce6d3ab0..92bef089e4 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -290,6 +290,7 @@ HEIMDAL_KRB5_OBJ_FILES = \ $(heimdalsrcdir)/lib/krb5/free_host_realm.o \ $(heimdalsrcdir)/lib/krb5/generate_seq_number.o \ $(heimdalsrcdir)/lib/krb5/generate_subkey.o \ + $(heimdalsrcdir)/lib/krb5/get_addrs.o \ $(heimdalsrcdir)/lib/krb5/get_cred.o \ $(heimdalsrcdir)/lib/krb5/get_default_principal.o \ $(heimdalsrcdir)/lib/krb5/get_default_realm.o \ diff --git a/source4/heimdal_build/krb5-glue.c b/source4/heimdal_build/krb5-glue.c index b41e3c0271..8a09a91f3e 100644 --- a/source4/heimdal_build/krb5-glue.c +++ b/source4/heimdal_build/krb5-glue.c @@ -25,39 +25,6 @@ #include "lib/socket/netif.h" #include "param/param.h" -/** - get the list of IP addresses for configured interfaces -*/ -krb5_error_code KRB5_LIB_FUNCTION krb5_get_all_client_addrs(krb5_context context, krb5_addresses *res) -{ - int i; - struct interface *ifaces; - - load_interfaces(NULL, lp_interfaces(global_loadparm), &ifaces); - - res->len = iface_count(ifaces); - res->val = malloc_array_p(HostAddress, res->len); - if (res->val == NULL) { - talloc_free(ifaces); - return ENOMEM; - } - for (i=0;i<res->len;i++) { - const char *ip = iface_n_ip(ifaces, i); - res->val[i].addr_type = AF_INET; - res->val[i].address.length = 4; - res->val[i].address.data = malloc(4); - if (res->val[i].address.data == NULL) { - talloc_free(ifaces); - return ENOMEM; - } - ((struct in_addr *)res->val[i].address.data)->s_addr = inet_addr(ip); - } - - talloc_free(ifaces); - - return 0; -} - #include "heimdal/lib/krb5/krb5_locl.h" const krb5_cc_ops krb5_scc_ops = { diff --git a/source4/include/includes.h b/source4/include/includes.h index 08d6cdb5f6..f925e836c5 100644 --- a/source4/include/includes.h +++ b/source4/include/includes.h @@ -40,8 +40,10 @@ #ifndef _PRINTF_ATTRIBUTE #define _PRINTF_ATTRIBUTE(a1, a2) PRINTF_ATTRIBUTE(a1, a2) #endif -#include "../lib/util/util.h" +#include "../lib/util/xfile.h" +#include "../lib/util/attr.h" #include "../lib/util/debug.h" +#include "../lib/util/util.h" #include "libcli/util/error.h" diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c index f5d92cd3c5..2fa07d0531 100644 --- a/source4/kdc/kpasswdd.c +++ b/source4/kdc/kpasswdd.c @@ -483,7 +483,9 @@ bool kpasswdd_process(struct kdc_server *kdc, ap_req = data_blob_const(&input->data[header_len], ap_req_len); krb_priv_req = data_blob_const(&input->data[header_len + ap_req_len], krb_priv_len); - nt_status = gensec_server_start(tmp_ctx, kdc->task->event_ctx, kdc->task->lp_ctx, kdc->task->msg_ctx, &gensec_security); + nt_status = gensec_server_start(tmp_ctx, kdc->task->event_ctx, + lp_gensec_settings(tmp_ctx, kdc->task->lp_ctx), kdc->task->msg_ctx, + &gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return false; diff --git a/source4/ldap_server/ldap_backend.c b/source4/ldap_server/ldap_backend.c index 32fc00832e..d0417107f1 100644 --- a/source4/ldap_server/ldap_backend.c +++ b/source4/ldap_server/ldap_backend.c @@ -74,6 +74,9 @@ NTSTATUS ldapsrv_backend_Init(struct ldapsrv_connection *conn) = gensec_use_kerberos_mechs(conn, backends, conn->server_credentials); int i, j = 0; for (i = 0; ops && ops[i]; i++) { + if (!gensec_security_ops_enabled(ops[i], conn->lp_ctx)) + continue; + if (ops[i]->sasl_name && ops[i]->server_start) { char *sasl_name = talloc_strdup(conn, ops[i]->sasl_name); diff --git a/source4/ldap_server/ldap_bind.c b/source4/ldap_server/ldap_bind.c index 20777e5261..0fe6fcce90 100644 --- a/source4/ldap_server/ldap_bind.c +++ b/source4/ldap_server/ldap_bind.c @@ -142,7 +142,7 @@ static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call) status = gensec_server_start(conn, conn->connection->event.ctx, - conn->lp_ctx, + lp_gensec_settings(conn, conn->lp_ctx), conn->connection->msg_ctx, &conn->gensec); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/lib/cmdline/popt_common.c b/source4/lib/cmdline/popt_common.c index 96d8b8b40a..712d99996c 100644 --- a/source4/lib/cmdline/popt_common.c +++ b/source4/lib/cmdline/popt_common.c @@ -23,7 +23,6 @@ #include "version.h" #include "lib/cmdline/popt_common.h" #include "param/param.h" -#include "dynconfig/dynconfig.h" /* Handle command line options: * -d,--debuglevel @@ -63,10 +62,7 @@ static void popt_samba_callback(poptContext con, if (reason == POPT_CALLBACK_REASON_POST) { if (lp_configfile(cmdline_lp_ctx) == NULL) { - if (getenv("SMB_CONF_PATH")) - lp_load(cmdline_lp_ctx, getenv("SMB_CONF_PATH")); - else - lp_load(cmdline_lp_ctx, dyn_CONFIGFILE); + lp_load_default(cmdline_lp_ctx); } /* Hook any 'every Samba program must do this, after * the smb.conf is setup' functions here */ @@ -82,11 +78,7 @@ static void popt_samba_callback(poptContext con, pname++; if (reason == POPT_CALLBACK_REASON_PRE) { - if (global_loadparm != NULL) { - cmdline_lp_ctx = global_loadparm; - } else { - cmdline_lp_ctx = global_loadparm = loadparm_init(talloc_autofree_context()); - } + cmdline_lp_ctx = loadparm_init(talloc_autofree_context()); /* Hook for 'almost the first thing to do in a samba program' here */ /* setup for panics */ diff --git a/source4/lib/cmdline/popt_credentials.c b/source4/lib/cmdline/popt_credentials.c index de5ea7c1b6..42ecac1eaa 100644 --- a/source4/lib/cmdline/popt_credentials.c +++ b/source4/lib/cmdline/popt_credentials.c @@ -60,7 +60,7 @@ static void popt_common_credentials_callback(poptContext con, } if (reason == POPT_CALLBACK_REASON_POST) { - cli_credentials_guess(cmdline_credentials, global_loadparm); + cli_credentials_guess(cmdline_credentials, cmdline_lp_ctx); if (!dont_ask) { cli_credentials_set_cmdline_callbacks(cmdline_credentials); diff --git a/source4/lib/ldb/common/attrib_handlers.c b/source4/lib/ldb/common/attrib_handlers.c index fb57e2dadc..5ec86b5b8f 100644 --- a/source4/lib/ldb/common/attrib_handlers.c +++ b/source4/lib/ldb/common/attrib_handlers.c @@ -240,7 +240,7 @@ int ldb_canonicalise_dn(struct ldb_context *ldb, void *mem_ctx, out->length = 0; out->data = NULL; - dn = ldb_dn_new(ldb, mem_ctx, (char *)in->data); + dn = ldb_dn_from_ldb_val(ldb, mem_ctx, in); if ( ! ldb_dn_validate(dn)) { return LDB_ERR_INVALID_DN_SYNTAX; } @@ -268,10 +268,10 @@ int ldb_comparison_dn(struct ldb_context *ldb, void *mem_ctx, struct ldb_dn *dn1 = NULL, *dn2 = NULL; int ret; - dn1 = ldb_dn_new(ldb, mem_ctx, (char *)v1->data); + dn1 = ldb_dn_from_ldb_val(ldb, mem_ctx, v1); if ( ! ldb_dn_validate(dn1)) return -1; - dn2 = ldb_dn_new(ldb, mem_ctx, (char *)v2->data); + dn2 = ldb_dn_from_ldb_val(ldb, mem_ctx, v2); if ( ! ldb_dn_validate(dn2)) { talloc_free(dn1); return -1; diff --git a/source4/lib/ldb/common/ldb_ldif.c b/source4/lib/ldb/common/ldb_ldif.c index fb93e17c6c..538ff8feaa 100644 --- a/source4/lib/ldb/common/ldb_ldif.c +++ b/source4/lib/ldb/common/ldb_ldif.c @@ -562,11 +562,11 @@ struct ldb_ldif *ldb_ldif_read(struct ldb_context *ldb, goto failed; } - msg->dn = ldb_dn_new(msg, ldb, (char *)value.data); + msg->dn = ldb_dn_from_ldb_val(msg, ldb, &value); if ( ! ldb_dn_validate(msg->dn)) { ldb_debug(ldb, LDB_DEBUG_ERROR, "Error: Unable to parse dn '%s'\n", - value.data); + (char *)value.data); goto failed; } diff --git a/source4/lib/ldb/common/ldb_match.c b/source4/lib/ldb/common/ldb_match.c index 64d0e54761..4cde739d67 100644 --- a/source4/lib/ldb/common/ldb_match.c +++ b/source4/lib/ldb/common/ldb_match.c @@ -147,7 +147,7 @@ static int ldb_match_equality(struct ldb_context *ldb, int ret; if (ldb_attr_dn(tree->u.equality.attr) == 0) { - valuedn = ldb_dn_new(ldb, ldb, (char *)tree->u.equality.value.data); + valuedn = ldb_dn_from_ldb_val(ldb, ldb, &tree->u.equality.value); if (valuedn == NULL) { return 0; } diff --git a/source4/lib/ldb/ldb.i b/source4/lib/ldb/ldb.i index 6013462225..6187096ab9 100644 --- a/source4/lib/ldb/ldb.i +++ b/source4/lib/ldb/ldb.i @@ -262,7 +262,6 @@ fail: { char *dn = ldb_dn_get_linearized($self), *ret; asprintf(&ret, "Dn('%s')", dn); - talloc_free(dn); return ret; } diff --git a/source4/lib/ldb/ldb_map/ldb_map.c b/source4/lib/ldb/ldb_map/ldb_map.c index fafbb63b0a..72d8378a07 100644 --- a/source4/lib/ldb/ldb_map/ldb_map.c +++ b/source4/lib/ldb/ldb_map/ldb_map.c @@ -626,7 +626,7 @@ static struct ldb_val ldb_dn_convert_local(struct ldb_module *module, void *mem_ struct ldb_dn *dn, *newdn; struct ldb_val newval; - dn = ldb_dn_new(mem_ctx, module->ldb, (char *)val->data); + dn = ldb_dn_from_ldb_val(mem_ctx, module->ldb, val); if (! ldb_dn_validate(dn)) { newval.length = 0; newval.data = NULL; @@ -652,7 +652,7 @@ static struct ldb_val ldb_dn_convert_remote(struct ldb_module *module, void *mem struct ldb_dn *dn, *newdn; struct ldb_val newval; - dn = ldb_dn_new(mem_ctx, module->ldb, (char *)val->data); + dn = ldb_dn_from_ldb_val(mem_ctx, module->ldb, val); if (! ldb_dn_validate(dn)) { newval.length = 0; newval.data = NULL; diff --git a/source4/lib/ldb/ldb_wrap.c b/source4/lib/ldb/ldb_wrap.c index bc9266a306..3cf5ec613a 100644 --- a/source4/lib/ldb/ldb_wrap.c +++ b/source4/lib/ldb/ldb_wrap.c @@ -2732,7 +2732,6 @@ SWIGINTERN char const *ldb_dn_canonical_ex_str(ldb_dn *self){ SWIGINTERN char *ldb_dn___repr__(ldb_dn *self){ char *dn = ldb_dn_get_linearized(self), *ret; asprintf(&ret, "Dn('%s')", dn); - talloc_free(dn); return ret; } SWIGINTERN ldb_dn *ldb_dn___add__(ldb_dn *self,ldb_dn *other){ diff --git a/source4/lib/messaging/pymessaging.c b/source4/lib/messaging/pymessaging.c index c2c23b679e..ad8f955466 100644 --- a/source4/lib/messaging/pymessaging.c +++ b/source4/lib/messaging/pymessaging.c @@ -34,6 +34,9 @@ PyAPI_DATA(PyTypeObject) messaging_Type; PyAPI_DATA(PyTypeObject) irpc_ClientConnectionType; +/* FIXME: This prototype should be in param/pyparam.h */ +struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx); + static bool server_id_from_py(PyObject *object, struct server_id *server_id) { if (!PyTuple_Check(object)) { @@ -80,7 +83,8 @@ PyObject *py_messaging_connect(PyTypeObject *self, PyObject *args, PyObject *kwa ev = s4_event_context_init(ret->mem_ctx); if (messaging_path == NULL) { - messaging_path = lp_messaging_path(ret->mem_ctx, global_loadparm); + messaging_path = lp_messaging_path(ret->mem_ctx, + py_default_loadparm_context(ret->mem_ctx)); } else { messaging_path = talloc_strdup(ret->mem_ctx, messaging_path); } @@ -334,7 +338,8 @@ PyObject *py_irpc_connect(PyTypeObject *self, PyObject *args, PyObject *kwargs) ev = s4_event_context_init(ret->mem_ctx); if (messaging_path == NULL) { - messaging_path = lp_messaging_path(ret->mem_ctx, global_loadparm); + messaging_path = lp_messaging_path(ret->mem_ctx, + py_default_loadparm_context(ret->mem_ctx)); } else { messaging_path = talloc_strdup(ret->mem_ctx, messaging_path); } diff --git a/source4/lib/registry/rpc.c b/source4/lib/registry/rpc.c index 3a16ae1db5..117951ed03 100644 --- a/source4/lib/registry/rpc.c +++ b/source4/lib/registry/rpc.c @@ -486,7 +486,7 @@ _PUBLIC_ WERROR reg_open_remote(struct registry_context **ctx, struct dcerpc_pipe *p; struct rpc_registry_context *rctx; - dcerpc_init(); + dcerpc_init(lp_ctx); rctx = talloc(NULL, struct rpc_registry_context); diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 0c3d032068..26cdac99a3 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -70,7 +70,7 @@ _PUBLIC_ NTSTATUS socket_create_with_ops(TALLOC_CTX *mem_ctx, const struct socke if (!(flags & SOCKET_FLAG_BLOCK) && type == SOCKET_TYPE_STREAM && - lp_parm_bool(global_loadparm, NULL, "socket", "testnonblock", false)) { + getenv("SOCKET_TESTNONBLOCK") != NULL) { (*new_sock)->flags |= SOCKET_FLAG_TESTNONBLOCK; } diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index 4baa0cfbb1..ec3afe8f7f 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -208,4 +208,6 @@ NTSTATUS socket_connect_multi(TALLOC_CTX *mem_ctx, const char *server_address, void set_socket_options(int fd, const char *options); void socket_set_flags(struct socket_context *socket, unsigned flags); +extern bool testnonblock; + #endif /* _SAMBA_SOCKET_H */ diff --git a/source4/lib/torture/subunit.c b/source4/lib/torture/subunit.c index 40d9b9731d..d5ee344596 100644 --- a/source4/lib/torture/subunit.c +++ b/source4/lib/torture/subunit.c @@ -20,7 +20,7 @@ #include "includes.h" #include "lib/torture/torture.h" -static void subunit_init(struct torture_context *ctx) +static void subunit_init(struct torture_results *results) { /* FIXME: register segv and bus handler */ } diff --git a/source4/lib/torture/torture.c b/source4/lib/torture/torture.c index 54ddc79be7..e465529f6b 100644 --- a/source4/lib/torture/torture.c +++ b/source4/lib/torture/torture.c @@ -24,25 +24,57 @@ #include "param/param.h" #include "system/filesys.h" +struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops) +{ + struct torture_results *results = talloc_zero(mem_ctx, struct torture_results); + + results->ui_ops = ui_ops; + results->returncode = true; + + if (ui_ops->init) + ui_ops->init(results); + + return results; +} + /** * Initialize a torture context */ struct torture_context *torture_context_init(struct event_context *event_ctx, - const struct torture_ui_ops *ui_ops) + struct torture_results *results) { struct torture_context *torture = talloc_zero(event_ctx, struct torture_context); - torture->ui_ops = ui_ops; - torture->returncode = true; - torture->ev = event_ctx; - if (ui_ops->init) - ui_ops->init(torture); + if (torture == NULL) + return NULL; + + torture->ev = event_ctx; + torture->results = talloc_reference(torture, results); return torture; } /** + * Create a sub torture context + */ +struct torture_context *torture_context_child(struct torture_context *parent) +{ + struct torture_context *subtorture = talloc_zero(parent, struct torture_context); + + if (subtorture == NULL) + return NULL; + + subtorture->level = parent->level+1; + subtorture->ev = talloc_reference(subtorture, parent->ev); + subtorture->lp_ctx = talloc_reference(subtorture, parent->lp_ctx); + subtorture->outputdir = talloc_reference(subtorture, parent->outputdir); + subtorture->results = talloc_reference(subtorture, parent->results); + + return subtorture; +} + +/** create a temporary directory. */ _PUBLIC_ NTSTATUS torture_temp_dir(struct torture_context *tctx, @@ -70,13 +102,13 @@ void torture_comment(struct torture_context *context, const char *comment, ...) va_list ap; char *tmp; - if (!context->ui_ops->comment) + if (!context->results->ui_ops->comment) return; va_start(ap, comment); tmp = talloc_vasprintf(context, comment, ap); - context->ui_ops->comment(context, tmp); + context->results->ui_ops->comment(context, tmp); talloc_free(tmp); } @@ -89,13 +121,13 @@ void torture_warning(struct torture_context *context, const char *comment, ...) va_list ap; char *tmp; - if (!context->ui_ops->warning) + if (!context->results->ui_ops->warning) return; va_start(ap, comment); tmp = talloc_vasprintf(context, comment, ap); - context->ui_ops->warning(context, tmp); + context->results->ui_ops->warning(context, tmp); talloc_free(tmp); } @@ -224,8 +256,8 @@ bool torture_run_suite(struct torture_context *context, char *old_testname; context->level++; - if (context->ui_ops->suite_start) - context->ui_ops->suite_start(context, suite); + if (context->results->ui_ops->suite_start) + context->results->ui_ops->suite_start(context, suite); old_testname = context->active_testname; if (old_testname != NULL) @@ -245,8 +277,8 @@ bool torture_run_suite(struct torture_context *context, talloc_free(context->active_testname); context->active_testname = old_testname; - if (context->ui_ops->suite_finish) - context->ui_ops->suite_finish(context, suite); + if (context->results->ui_ops->suite_finish) + context->results->ui_ops->suite_finish(context, suite); context->level--; @@ -257,19 +289,19 @@ void torture_ui_test_start(struct torture_context *context, struct torture_tcase *tcase, struct torture_test *test) { - if (context->ui_ops->test_start) - context->ui_ops->test_start(context, tcase, test); + if (context->results->ui_ops->test_start) + context->results->ui_ops->test_start(context, tcase, test); } void torture_ui_test_result(struct torture_context *context, enum torture_result result, const char *comment) { - if (context->ui_ops->test_result) - context->ui_ops->test_result(context, result, comment); + if (context->results->ui_ops->test_result) + context->results->ui_ops->test_result(context, result, comment); if (result == TORTURE_ERROR || result == TORTURE_FAIL) - context->returncode = false; + context->results->returncode = false; } static bool internal_torture_run_test(struct torture_context *context, @@ -347,8 +379,8 @@ bool torture_run_tcase(struct torture_context *context, context->level++; context->active_tcase = tcase; - if (context->ui_ops->tcase_start) - context->ui_ops->tcase_start(context, tcase); + if (context->results->ui_ops->tcase_start) + context->results->ui_ops->tcase_start(context, tcase); if (tcase->fixture_persistent && tcase->setup && !tcase->setup(context, &tcase->data)) { @@ -378,8 +410,8 @@ bool torture_run_tcase(struct torture_context *context, done: context->active_tcase = NULL; - if (context->ui_ops->tcase_finish) - context->ui_ops->tcase_finish(context, tcase); + if (context->results->ui_ops->tcase_finish) + context->results->ui_ops->tcase_finish(context, tcase); context->level--; diff --git a/source4/lib/torture/torture.h b/source4/lib/torture/torture.h index ea5cd70961..f06ffe012b 100644 --- a/source4/lib/torture/torture.h +++ b/source4/lib/torture/torture.h @@ -25,6 +25,7 @@ struct torture_test; struct torture_context; struct torture_suite; struct torture_tcase; +struct torture_results; enum torture_result { TORTURE_OK=0, @@ -39,7 +40,7 @@ enum torture_result { */ struct torture_ui_ops { - void (*init) (struct torture_context *); + void (*init) (struct torture_results *); void (*comment) (struct torture_context *, const char *); void (*warning) (struct torture_context *, const char *); void (*suite_start) (struct torture_context *, struct torture_suite *); @@ -73,44 +74,67 @@ void torture_ui_test_result(struct torture_context *context, struct torture_context { - const struct torture_ui_ops *ui_ops; - void *ui_data; + struct torture_results *results; char *active_testname; struct torture_test *active_test; struct torture_tcase *active_tcase; - bool quiet; /* Whether tests should avoid writing output to stdout */ - enum torture_result last_result; char *last_reason; - bool returncode; - + /** Directory used for temporary test data */ const char *outputdir; + + /** Indentation level */ int level; + + /** Event context */ struct event_context *ev; + /** Loadparm context (will go away in favor of torture_setting_ at some point) */ struct loadparm_context *lp_ctx; }; +struct torture_results +{ + const struct torture_ui_ops *ui_ops; + void *ui_data; + + /** Whether tests should avoid writing output to stdout */ + bool quiet; + + bool returncode; + + +}; + /* * Describes a particular torture test */ struct torture_test { + /** Short unique name for the test. */ const char *name; + + /** Long description for the test. */ const char *description; + + /** Whether this is a dangerous test + * (can corrupt the remote servers data or bring it down). */ bool dangerous; - /* Function to call to run this test */ + + /** Function to call to run this test */ bool (*run) (struct torture_context *torture_ctx, struct torture_tcase *tcase, struct torture_test *test); struct torture_test *prev, *next; - /* Pointer to the actual test function. This is run by the - * run() function above. */ + /** Pointer to the actual test function. This is run by the + * run() function above. */ void *fn; + + /** Use data for this test */ const void *data; }; @@ -390,8 +414,11 @@ bool torture_suite_init_tcase(struct torture_suite *suite, struct torture_tcase *tcase, const char *name); -struct torture_context *torture_context_init(struct event_context *event_ctx, - const struct torture_ui_ops *ui_ops); +struct torture_context *torture_context_init(struct event_context *event_ctx, struct torture_results *results); + +struct torture_results *torture_results_init(TALLOC_CTX *mem_ctx, const struct torture_ui_ops *ui_ops); + +struct torture_context *torture_context_child(struct torture_context *tctx); extern const struct torture_ui_ops torture_subunit_ui_ops; diff --git a/source4/lib/wmi/wmicore.c b/source4/lib/wmi/wmicore.c index a853f26035..7624946536 100644 --- a/source4/lib/wmi/wmicore.c +++ b/source4/lib/wmi/wmicore.c @@ -37,9 +37,10 @@ struct IWbemContext; DEBUG(1, ("OK : %s\n", msg)); \ } -void wmi_init(struct com_context **ctx, struct cli_credentials *credentials) +void wmi_init(struct com_context **ctx, struct cli_credentials *credentials, + struct loadparm_context *lp_ctx) { - dcerpc_init(); + dcerpc_init(lp_ctx); ndr_table_init(); /* FIXME: Register DCOM proxies? */ diff --git a/source4/libcli/cliconnect.c b/source4/libcli/cliconnect.c index e1f5e9ab50..dda05c8d73 100644 --- a/source4/libcli/cliconnect.c +++ b/source4/libcli/cliconnect.c @@ -35,12 +35,14 @@ bool smbcli_socket_connect(struct smbcli_state *cli, const char *server, struct event_context *ev_ctx, struct resolve_context *resolve_ctx, struct smbcli_options *options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + const char *socket_options) { struct smbcli_socket *sock; sock = smbcli_sock_connect_byname(server, ports, NULL, - resolve_ctx, ev_ctx); + resolve_ctx, ev_ctx, + socket_options); if (sock == NULL) return false; @@ -71,7 +73,8 @@ NTSTATUS smbcli_negprot(struct smbcli_state *cli, bool unicode, int maxprotocol) NTSTATUS smbcli_session_setup(struct smbcli_state *cli, struct cli_credentials *credentials, const char *workgroup, - struct smbcli_session_options options) + struct smbcli_session_options options, + struct gensec_settings *gensec_settings) { struct smb_composite_sesssetup setup; NTSTATUS status; @@ -84,6 +87,7 @@ NTSTATUS smbcli_session_setup(struct smbcli_state *cli, setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.credentials = credentials; setup.in.workgroup = workgroup; + setup.in.gensec_settings = gensec_settings; status = smb_composite_sesssetup(cli->session, &setup); @@ -144,12 +148,14 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, const char **ports, const char *sharename, const char *devtype, + const char *socket_options, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, struct event_context *ev, struct smbcli_options *options, struct smbcli_session_options *session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { struct smbcli_tree *tree; NTSTATUS status; @@ -159,10 +165,12 @@ NTSTATUS smbcli_full_connection(TALLOC_CTX *parent_ctx, status = smbcli_tree_full_connection(parent_ctx, &tree, host, ports, sharename, devtype, + socket_options, credentials, resolve_ctx, ev, options, session_options, - iconv_convenience); + iconv_convenience, + gensec_settings); if (!NT_STATUS_IS_OK(status)) { goto done; } diff --git a/source4/libcli/ldap/ldap_bind.c b/source4/libcli/ldap/ldap_bind.c index b66232c02e..a12f7652a5 100644 --- a/source4/libcli/ldap/ldap_bind.c +++ b/source4/libcli/ldap/ldap_bind.c @@ -224,7 +224,8 @@ _PUBLIC_ NTSTATUS ldap_bind_sasl(struct ldap_connection *conn, gensec_init(lp_ctx); status = gensec_client_start(conn, &conn->gensec, - conn->event.event_ctx, lp_ctx); + conn->event.event_ctx, + lp_gensec_settings(conn, lp_ctx)); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status))); goto failed; diff --git a/source4/libcli/libcli.h b/source4/libcli/libcli.h index 163852d90a..a4bd727f4c 100644 --- a/source4/libcli/libcli.h +++ b/source4/libcli/libcli.h @@ -64,6 +64,7 @@ enum brl_type { #include "libcli/raw/libcliraw.h" +struct gensec_settings; #include "libcli/libcli_proto.h" #endif /* __LIBCLI_H__ */ diff --git a/source4/libcli/raw/clisocket.c b/source4/libcli/raw/clisocket.c index d51ffbaa74..1fbbfe3581 100644 --- a/source4/libcli/raw/clisocket.c +++ b/source4/libcli/raw/clisocket.c @@ -50,7 +50,8 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, const char **ports, const char *host_name, struct resolve_context *resolve_ctx, - struct event_context *event_ctx) + struct event_context *event_ctx, + const char *socket_options) { struct composite_context *result, *ctx; struct sock_connect_state *state; @@ -77,7 +78,7 @@ struct composite_context *smbcli_sock_connect_send(TALLOC_CTX *mem_ctx, for (i=0;ports[i];i++) { state->ports[i] = atoi(ports[i]); } - state->socket_options = lp_socket_options(global_loadparm); + state->socket_options = talloc_reference(state, socket_options); ctx = socket_connect_multi_send(state, host_addr, state->num_ports, state->ports, @@ -153,12 +154,13 @@ NTSTATUS smbcli_sock_connect(TALLOC_CTX *mem_ctx, const char *host_name, struct resolve_context *resolve_ctx, struct event_context *event_ctx, + const char *socket_options, struct smbcli_socket **result) { struct composite_context *c = smbcli_sock_connect_send(mem_ctx, host_addr, ports, host_name, resolve_ctx, - event_ctx); + event_ctx, socket_options); return smbcli_sock_connect_recv(c, mem_ctx, result); } @@ -188,7 +190,8 @@ resolve a hostname and connect _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, TALLOC_CTX *mem_ctx, struct resolve_context *resolve_ctx, - struct event_context *event_ctx) + struct event_context *event_ctx, + const char *socket_options) { int name_type = NBT_NAME_SERVER; const char *address; @@ -230,7 +233,8 @@ _PUBLIC_ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, cons } status = smbcli_sock_connect(mem_ctx, address, ports, name, resolve_ctx, - event_ctx, &result); + event_ctx, + socket_options, &result); if (!NT_STATUS_IS_OK(status)) { DEBUG(9, ("smbcli_sock_connect failed: %s\n", diff --git a/source4/libcli/raw/clitree.c b/source4/libcli/raw/clitree.c index 61cbfa7ecb..984aa70247 100644 --- a/source4/libcli/raw/clitree.c +++ b/source4/libcli/raw/clitree.c @@ -173,12 +173,14 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, struct smbcli_tree **ret_tree, const char *dest_host, const char **dest_ports, const char *service, const char *service_type, + const char *socket_options, struct cli_credentials *credentials, struct resolve_context *resolve_ctx, struct event_context *ev, struct smbcli_options *options, struct smbcli_session_options *session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { struct smb_composite_connect io; NTSTATUS status; @@ -189,10 +191,12 @@ NTSTATUS smbcli_tree_full_connection(TALLOC_CTX *parent_ctx, io.in.dest_host = dest_host; io.in.dest_ports = dest_ports; + io.in.socket_options = socket_options; io.in.called_name = strupper_talloc(tmp_ctx, dest_host); io.in.service = service; io.in.service_type = service_type; io.in.credentials = credentials; + io.in.gensec_settings = gensec_settings; io.in.fallback_to_anonymous = false; /* This workgroup gets sent out by the SPNEGO session setup. diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index 98f18b1ed5..7757d10099 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -32,6 +32,7 @@ struct smbcli_transport; /* forward declare */ struct resolve_context; struct cli_credentials; +struct gensec_settings; /* default timeout for all smb requests */ #define SMB_REQUEST_TIMEOUT 60 @@ -376,7 +377,8 @@ NTSTATUS smb_raw_trans(struct smbcli_tree *tree, struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, TALLOC_CTX *mem_ctx, struct resolve_context *resolve_ctx, - struct event_context *event_ctx); + struct event_context *event_ctx, + const char *socket_options); void smbcli_sock_dead(struct smbcli_socket *sock); #endif /* __LIBCLI_RAW__H__ */ diff --git a/source4/libcli/raw/rawfile.c b/source4/libcli/raw/rawfile.c index d174fbfc28..8cabac6d04 100644 --- a/source4/libcli/raw/rawfile.c +++ b/source4/libcli/raw/rawfile.c @@ -33,7 +33,7 @@ /** Return a string representing a CIFS attribute for a file. **/ -_PUBLIC_ char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib) +char *attrib_string(TALLOC_CTX *mem_ctx, uint32_t attrib) { int i, len; const struct { diff --git a/source4/libcli/resolve/nbtlist.c b/source4/libcli/resolve/nbtlist.c index 531ce6098f..ec4cfb81b4 100644 --- a/source4/libcli/resolve/nbtlist.c +++ b/source4/libcli/resolve/nbtlist.c @@ -142,7 +142,7 @@ struct composite_context *resolve_name_nbtlist_send(TALLOC_CTX *mem_ctx, } state->nbtsock = nbt_name_socket_init(state, event_ctx, - lp_iconv_convenience(global_loadparm)); + global_iconv_convenience); if (composite_nomem(state->nbtsock, c)) return c; /* count the address_list size */ diff --git a/source4/libcli/smb2/connect.c b/source4/libcli/smb2/connect.c index bbfcf010ae..c7613841b8 100644 --- a/source4/libcli/smb2/connect.c +++ b/source4/libcli/smb2/connect.c @@ -33,6 +33,9 @@ struct smb2_connect_state { struct resolve_context *resolve_ctx; const char *host; const char *share; + const char **ports; + const char *socket_options; + struct gensec_settings *gensec_settings; struct smbcli_options options; struct smb2_negprot negprot; struct smb2_tree_connect tcon; @@ -137,9 +140,8 @@ static void continue_negprot(struct smb2_request *req) } break; } - - state->session = smb2_session_init(transport, global_loadparm, state, true); + state->session = smb2_session_init(transport, state->gensec_settings, state, true); if (composite_nomem(state->session, c)) return; creq = smb2_session_setup_spnego_send(state->session, state->credentials); @@ -209,15 +211,16 @@ static void continue_resolve(struct composite_context *creq) const char **ports; const char *default_ports[] = { "445", NULL }; - ports = lp_parm_string_list(state, global_loadparm, NULL, "smb2", "ports", NULL); - if (ports == NULL) { - ports = default_ports; - } - c->status = resolve_name_recv(creq, state, &addr); if (!composite_is_ok(c)) return; - creq = smbcli_sock_connect_send(state, addr, ports, state->host, state->resolve_ctx, c->event_ctx); + if (state->ports == NULL) { + ports = default_ports; + } else { + ports = state->ports; + } + + creq = smbcli_sock_connect_send(state, addr, ports, state->host, state->resolve_ctx, c->event_ctx, state->socket_options); composite_continue(c, creq, continue_socket, c); } @@ -228,11 +231,14 @@ static void continue_resolve(struct composite_context *creq) */ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, const char *host, + const char **ports, const char *share, struct resolve_context *resolve_ctx, struct cli_credentials *credentials, struct event_context *ev, - struct smbcli_options *options) + struct smbcli_options *options, + const char *socket_options, + struct gensec_settings *gensec_settings) { struct composite_context *c; struct smb2_connect_state *state; @@ -250,9 +256,12 @@ struct composite_context *smb2_connect_send(TALLOC_CTX *mem_ctx, state->options = *options; state->host = talloc_strdup(c, host); if (composite_nomem(state->host, c)) return c; + state->ports = talloc_reference(state, ports); state->share = talloc_strdup(c, share); if (composite_nomem(state->share, c)) return c; state->resolve_ctx = talloc_reference(state, resolve_ctx); + state->socket_options = talloc_reference(state, socket_options); + state->gensec_settings = talloc_reference(state, gensec_settings); ZERO_STRUCT(name); name.name = host; @@ -283,15 +292,20 @@ NTSTATUS smb2_connect_recv(struct composite_context *c, TALLOC_CTX *mem_ctx, sync version of smb2_connect */ NTSTATUS smb2_connect(TALLOC_CTX *mem_ctx, - const char *host, const char *share, + const char *host, const char **ports, + const char *share, struct resolve_context *resolve_ctx, struct cli_credentials *credentials, struct smb2_tree **tree, struct event_context *ev, - struct smbcli_options *options) + struct smbcli_options *options, + const char *socket_options, + struct gensec_settings *gensec_settings) { - struct composite_context *c = smb2_connect_send(mem_ctx, host, share, - resolve_ctx, - credentials, ev, options); + struct composite_context *c = smb2_connect_send(mem_ctx, host, ports, + share, resolve_ctx, + credentials, ev, options, + socket_options, + gensec_settings); return smb2_connect_recv(c, mem_ctx, tree); } diff --git a/source4/libcli/smb2/session.c b/source4/libcli/smb2/session.c index 31b3e942e9..127bb9bcae 100644 --- a/source4/libcli/smb2/session.c +++ b/source4/libcli/smb2/session.c @@ -25,13 +25,12 @@ #include "libcli/smb2/smb2_calls.h" #include "libcli/composite/composite.h" #include "auth/gensec/gensec.h" -#include "param/param.h" /** initialise a smb2_session structure */ struct smb2_session *smb2_session_init(struct smb2_transport *transport, - struct loadparm_context *lp_ctx, + struct gensec_settings *settings, TALLOC_CTX *parent_ctx, bool primary) { struct smb2_session *session; @@ -50,7 +49,7 @@ struct smb2_session *smb2_session_init(struct smb2_transport *transport, /* prepare a gensec context for later use */ status = gensec_client_start(session, &session->gensec, session->transport->socket->event.ctx, - lp_ctx); + settings); if (!NT_STATUS_IS_OK(status)) { talloc_free(session); return NULL; diff --git a/source4/libcli/smb2/smb2_calls.h b/source4/libcli/smb2/smb2_calls.h index f66236af30..ec246b209d 100644 --- a/source4/libcli/smb2/smb2_calls.h +++ b/source4/libcli/smb2/smb2_calls.h @@ -107,4 +107,5 @@ struct smb2_setinfo { struct cli_credentials; struct event_context; struct resolve_context; +struct gensec_settings; #include "libcli/smb2/smb2_proto.h" diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 0d97a6c54b..980a418619 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -29,6 +29,7 @@ #include "libcli/resolve/resolve.h" #include "auth/credentials/credentials.h" #include "librpc/gen_ndr/ndr_nbt.h" +#include "param/param.h" /* the stages of this call */ enum connect_stage {CONNECT_RESOLVE, @@ -256,6 +257,7 @@ static NTSTATUS connect_negprot(struct composite_context *c, state->io_setup->in.capabilities = state->transport->negotiate.capabilities; state->io_setup->in.credentials = io->in.credentials; state->io_setup->in.workgroup = io->in.workgroup; + state->io_setup->in.gensec_settings = io->in.gensec_settings; state->creq = smb_composite_sesssetup_send(state->session, state->io_setup); NT_STATUS_HAVE_NO_MEMORY(state->creq); @@ -375,7 +377,8 @@ static NTSTATUS connect_resolve(struct composite_context *c, state->creq = smbcli_sock_connect_send(state, address, io->in.dest_ports, io->in.dest_host, - NULL, c->event_ctx); + NULL, c->event_ctx, + io->in.socket_options); NT_STATUS_HAVE_NO_MEMORY(state->creq); state->stage = CONNECT_SOCKET; @@ -467,6 +470,7 @@ struct composite_context *smb_composite_connect_send(struct smb_composite_connec state = talloc_zero(c, struct connect_state); if (state == NULL) goto failed; + if (io->in.gensec_settings == NULL) goto failed; state->io = io; c->state = COMPOSITE_STATE_IN_PROGRESS; diff --git a/source4/libcli/smb_composite/fetchfile.c b/source4/libcli/smb_composite/fetchfile.c index cbe2289a55..a19898efae 100644 --- a/source4/libcli/smb_composite/fetchfile.c +++ b/source4/libcli/smb_composite/fetchfile.c @@ -138,12 +138,14 @@ struct composite_context *smb_composite_fetchfile_send(struct smb_composite_fetc state->connect->in.dest_host = io->in.dest_host; state->connect->in.dest_ports = io->in.ports; + state->connect->in.socket_options = io->in.socket_options; state->connect->in.called_name = io->in.called_name; state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; state->connect->in.credentials = io->in.credentials; state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; + state->connect->in.gensec_settings = io->in.gensec_settings; state->connect->in.iconv_convenience = io->in.iconv_convenience; state->connect->in.options = io->in.options; diff --git a/source4/libcli/smb_composite/fsinfo.c b/source4/libcli/smb_composite/fsinfo.c index f148fb8bf6..7c9c7963f4 100644 --- a/source4/libcli/smb_composite/fsinfo.c +++ b/source4/libcli/smb_composite/fsinfo.c @@ -146,6 +146,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.dest_host = io->in.dest_host; state->connect->in.dest_ports = io->in.dest_ports; + state->connect->in.socket_options = io->in.socket_options; state->connect->in.called_name = io->in.called_name; state->connect->in.service = io->in.service; state->connect->in.service_type = io->in.service_type; @@ -153,6 +154,7 @@ struct composite_context *smb_composite_fsinfo_send(struct smbcli_tree *tree, state->connect->in.fallback_to_anonymous = false; state->connect->in.workgroup = io->in.workgroup; state->connect->in.iconv_convenience = io->in.iconv_convenience; + state->connect->in.gensec_settings = io->in.gensec_settings; state->connect->in.options = tree->session->transport->options; state->connect->in.session_options = tree->session->options; diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 2ca12a5898..7c9d1fb731 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -408,7 +408,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, smbcli_temp_set_signing(session->transport); status = gensec_client_start(session, &session->gensec, c->event_ctx, - global_loadparm); + io->in.gensec_settings); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(status))); return status; @@ -442,12 +442,13 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, status = gensec_start_mech_by_oid(session->gensec, chosen_oid); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + gensec_get_name_by_oid(session->gensec, chosen_oid), nt_errstr(status))); chosen_oid = GENSEC_OID_NTLMSSP; status = gensec_start_mech_by_oid(session->gensec, chosen_oid); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set (fallback) GENSEC client mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + gensec_get_name_by_oid(session->gensec, chosen_oid), + nt_errstr(status))); return status; } } @@ -457,7 +458,7 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, status = gensec_start_mech_by_oid(session->gensec, chosen_oid); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start set GENSEC client mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + gensec_get_name_by_oid(session->gensec, chosen_oid), nt_errstr(status))); } } @@ -475,7 +476,8 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed initial gensec_update with mechanism %s: %s\n", - gensec_get_name_by_oid(chosen_oid), nt_errstr(status))); + gensec_get_name_by_oid(session->gensec, chosen_oid), + nt_errstr(status))); return status; } state->gensec_status = status; diff --git a/source4/libcli/smb_composite/smb_composite.h b/source4/libcli/smb_composite/smb_composite.h index fd1b95e64f..a1e1e99d7e 100644 --- a/source4/libcli/smb_composite/smb_composite.h +++ b/source4/libcli/smb_composite/smb_composite.h @@ -53,6 +53,7 @@ struct smb_composite_fetchfile { const char *called_name; const char *service; const char *service_type; + const char *socket_options; struct cli_credentials *credentials; const char *workgroup; const char *filename; @@ -60,6 +61,7 @@ struct smb_composite_fetchfile { struct smbcli_session_options session_options; struct resolve_context *resolve_ctx; struct smb_iconv_convenience *iconv_convenience; + struct gensec_settings *gensec_settings; } in; struct { uint8_t *data; @@ -93,6 +95,7 @@ struct smb_composite_connect { struct { const char *dest_host; const char **dest_ports; + const char *socket_options; const char *called_name; const char *service; const char *service_type; @@ -102,6 +105,7 @@ struct smb_composite_connect { struct smbcli_options options; struct smbcli_session_options session_options; struct smb_iconv_convenience *iconv_convenience; + struct gensec_settings *gensec_settings; } in; struct { struct smbcli_tree *tree; @@ -120,6 +124,7 @@ struct smb_composite_sesssetup { uint32_t capabilities; struct cli_credentials *credentials; const char *workgroup; + struct gensec_settings *gensec_settings; } in; struct { uint16_t vuid; @@ -133,6 +138,7 @@ struct smb_composite_fsinfo { struct { const char *dest_host; const char **dest_ports; + const char *socket_options; const char *called_name; const char *service; const char *service_type; @@ -140,6 +146,7 @@ struct smb_composite_fsinfo { const char *workgroup; enum smb_fsinfo_level level; struct smb_iconv_convenience *iconv_convenience; + struct gensec_settings *gensec_settings; } in; struct { diff --git a/source4/libcli/swig/libcli_smb.i b/source4/libcli/swig/libcli_smb.i index 0162b7b66a..0f9116d7f9 100644 --- a/source4/libcli/swig/libcli_smb.i +++ b/source4/libcli/swig/libcli_smb.i @@ -12,6 +12,7 @@ struct smbcli_socket *smbcli_sock_connect_byname(const char *host, const char **ports, TALLOC_CTX *mem_ctx, struct resolve_context *resolve_ctx, - struct event_context *event_ctx); + struct event_context *event_ctx, + const char *socket_options); void smbcli_sock_dead(struct smbcli_socket *sock); diff --git a/source4/libcli/swig/libcli_smb_wrap.c b/source4/libcli/swig/libcli_smb_wrap.c index 99bbdc7f96..a4e4db726e 100644 --- a/source4/libcli/swig/libcli_smb_wrap.c +++ b/source4/libcli/swig/libcli_smb_wrap.c @@ -2609,6 +2609,7 @@ SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(s TALLOC_CTX *arg3 = (TALLOC_CTX *) 0 ; struct resolve_context *arg4 = (struct resolve_context *) 0 ; struct event_context *arg5 = (struct event_context *) 0 ; + char *arg6 = (char *) 0 ; int res1 ; char *buf1 = 0 ; int alloc1 = 0 ; @@ -2618,18 +2619,22 @@ SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(s int res4 = 0 ; void *argp5 = 0 ; int res5 = 0 ; + int res6 ; + char *buf6 = 0 ; + int alloc6 = 0 ; PyObject * obj0 = 0 ; PyObject * obj1 = 0 ; PyObject * obj2 = 0 ; PyObject * obj3 = 0 ; + PyObject * obj4 = 0 ; char * kwnames[] = { - (char *) "host",(char *) "ports",(char *) "resolve_ctx",(char *) "event_ctx", NULL + (char *) "host",(char *) "ports",(char *) "resolve_ctx",(char *) "event_ctx",(char *) "socket_options", NULL }; struct smbcli_socket *result = 0 ; arg5 = event_context_init(NULL); arg3 = NULL; - if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|O:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2,&obj3)) SWIG_fail; + if (!PyArg_ParseTupleAndKeywords(args,kwargs,(char *)"OOO|OO:smbcli_sock_connect_byname",kwnames,&obj0,&obj1,&obj2,&obj3,&obj4)) SWIG_fail; res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); if (!SWIG_IsOK(res1)) { SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "smbcli_sock_connect_byname" "', argument " "1"" of type '" "char const *""'"); @@ -2652,12 +2657,21 @@ SWIGINTERN PyObject *_wrap_smbcli_sock_connect_byname(PyObject *SWIGUNUSEDPARM(s } arg5 = (struct event_context *)(argp5); } - result = (struct smbcli_socket *)smbcli_sock_connect_byname((char const *)arg1,(char const **)arg2,arg3,arg4,arg5); + if (obj4) { + res6 = SWIG_AsCharPtrAndSize(obj4, &buf6, NULL, &alloc6); + if (!SWIG_IsOK(res6)) { + SWIG_exception_fail(SWIG_ArgError(res6), "in method '" "smbcli_sock_connect_byname" "', argument " "6"" of type '" "char const *""'"); + } + arg6 = (char *)(buf6); + } + result = (struct smbcli_socket *)smbcli_sock_connect_byname((char const *)arg1,(char const **)arg2,arg3,arg4,arg5,(char const *)arg6); resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_smbcli_socket, 0 | 0 ); if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + if (alloc6 == SWIG_NEWOBJ) free((char*)buf6); return resultobj; fail: if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); + if (alloc6 == SWIG_NEWOBJ) free((char*)buf6); return NULL; } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 2257955c76..0185e66c39 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "param/param.h" #include "librpc/ndr/libndr.h" /* This map was extracted by the ERRMAPEXTRACT smbtorture command. @@ -1157,8 +1156,10 @@ static const struct { {NT_STATUS(0x80000025), W_ERROR(0x962)}, {NT_STATUS(0x80000288), W_ERROR(0x48d)}, {NT_STATUS(0x80000289), W_ERROR(0x48e)}, - {NT_STATUS_OK, WERR_OK}}; + {NT_STATUS_OK, WERR_OK} +}; +bool ntstatus_check_dos_mapping = true; /* check if a DOS encoded NTSTATUS code maps to the given NTSTATUS code @@ -1169,7 +1170,7 @@ bool ntstatus_dos_equal(NTSTATUS status1, NTSTATUS status2) the mapping of dos codes, as we want to catch the cases where a forced dos code is needed */ - if (lp_nt_status_support(global_loadparm)) { + if (ntstatus_check_dos_mapping) { return NT_STATUS_V(status1) == NT_STATUS_V(status2); } diff --git a/source4/libcli/util/nterr.c b/source4/libcli/util/nterr.c index e95f0228c1..e94ed36d39 100644 --- a/source4/libcli/util/nterr.c +++ b/source4/libcli/util/nterr.c @@ -548,6 +548,7 @@ static const nt_err_code_struct nt_errs[] = { "NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED", NT_STATUS_CURRENT_DOMAIN_NOT_ALLOWED }, { "NT_STATUS_OBJECTID_NOT_FOUND", NT_STATUS_OBJECTID_NOT_FOUND }, { "NT_STATUS_DOWNGRADE_DETECTED", NT_STATUS_DOWNGRADE_DETECTED }, + { "NT_STATUS_DS_BUSY", NT_STATUS_DS_BUSY }, { "STATUS_MORE_ENTRIES", STATUS_MORE_ENTRIES }, { "STATUS_SOME_UNMAPPED", STATUS_SOME_UNMAPPED }, { "STATUS_NOTIFY_CLEANUP", STATUS_NOTIFY_CLEANUP }, diff --git a/source4/libnet/groupinfo.c b/source4/libnet/groupinfo.c index 1da6646702..5c94c34b1d 100644 --- a/source4/libnet/groupinfo.c +++ b/source4/libnet/groupinfo.c @@ -83,8 +83,8 @@ static void continue_groupinfo_lookup(struct rpc_request *req) if (s->monitor_fn) { msg.type = mon_SamrLookupName; msg_lookup = talloc(s, struct msg_rpc_lookup_name); - msg_lookup->rid = s->lookup.out.rids.ids; - msg_lookup->count = s->lookup.out.rids.count; + msg_lookup->rid = s->lookup.out.rids->ids; + msg_lookup->count = s->lookup.out.rids->count; msg.data = (void*)msg_lookup; msg.data_size = sizeof(*msg_lookup); @@ -94,7 +94,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req) /* have we actually got name resolved - we're looking for only one at the moment */ - if (s->lookup.out.rids.count == 0) { + if (s->lookup.out.rids->count == 0) { composite_error(c, NT_STATUS_NO_SUCH_USER); } @@ -103,7 +103,7 @@ static void continue_groupinfo_lookup(struct rpc_request *req) /* prepare parameters for LookupNames */ s->opengroup.in.domain_handle = &s->domain_handle; s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - s->opengroup.in.rid = s->lookup.out.rids.ids[0]; + s->opengroup.in.rid = s->lookup.out.rids->ids[0]; s->opengroup.out.group_handle = &s->group_handle; /* send request */ @@ -152,6 +152,8 @@ static void continue_groupinfo_opengroup(struct rpc_request *req) /* prepare parameters for QueryGroupInfo call */ s->querygroupinfo.in.group_handle = &s->group_handle; s->querygroupinfo.in.level = s->level; + s->querygroupinfo.out.info = talloc(s, union samr_GroupInfo *); + if (composite_nomem(s->querygroupinfo.out.info, c)) return; /* queue rpc call, set event handling and new state */ querygroup_req = dcerpc_samr_QueryGroupInfo_send(s->pipe, c, &s->querygroupinfo); @@ -185,7 +187,7 @@ static void continue_groupinfo_getgroup(struct rpc_request *req) return; } - s->info = talloc_steal(s, s->querygroupinfo.out.info); + s->info = talloc_steal(s, *s->querygroupinfo.out.info); /* issue a monitor message */ if (s->monitor_fn) { @@ -301,7 +303,11 @@ struct composite_context *libnet_rpc_groupinfo_send(struct dcerpc_pipe *p, s->lookup.in.names[0].string = talloc_strdup(s, io->in.groupname); if (composite_nomem(s->lookup.in.names[0].string, c)) return c; - + s->lookup.out.rids = talloc_zero(s, struct samr_Ids); + s->lookup.out.types = talloc_zero(s, struct samr_Ids); + if (composite_nomem(s->lookup.out.rids, c)) return c; + if (composite_nomem(s->lookup.out.types, c)) return c; + /* send request */ lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookup); if (composite_nomem(lookup_req, c)) return c; diff --git a/source4/libnet/groupman.c b/source4/libnet/groupman.c index 58d5742336..4dfb2d8aab 100644 --- a/source4/libnet/groupman.c +++ b/source4/libnet/groupman.c @@ -174,6 +174,10 @@ struct composite_context* libnet_rpc_groupdel_send(struct dcerpc_pipe *p, s->lookupname.in.num_names = 1; s->lookupname.in.names = talloc_zero(s, struct lsa_String); s->lookupname.in.names->string = io->in.groupname; + s->lookupname.out.rids = talloc_zero(s, struct samr_Ids); + s->lookupname.out.types = talloc_zero(s, struct samr_Ids); + if (composite_nomem(s->lookupname.out.rids, c)) return c; + if (composite_nomem(s->lookupname.out.types, c)) return c; /* send the request */ lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname); @@ -205,12 +209,12 @@ static void continue_groupdel_name_found(struct rpc_request *req) /* what to do when there's no group account to delete and what if there's more than one rid resolved */ - if (!s->lookupname.out.rids.count) { + if (!s->lookupname.out.rids->count) { c->status = NT_STATUS_NO_SUCH_GROUP; composite_error(c, c->status); return; - } else if (!s->lookupname.out.rids.count > 1) { + } else if (!s->lookupname.out.rids->count > 1) { c->status = NT_STATUS_INVALID_ACCOUNT_NAME; composite_error(c, c->status); return; @@ -218,7 +222,7 @@ static void continue_groupdel_name_found(struct rpc_request *req) /* prepare the arguments for rpc call */ s->opengroup.in.domain_handle = &s->domain_handle; - s->opengroup.in.rid = s->lookupname.out.rids.ids[0]; + s->opengroup.in.rid = s->lookupname.out.rids->ids[0]; s->opengroup.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; s->opengroup.out.group_handle = &s->group_handle; diff --git a/source4/libnet/libnet_domain.c b/source4/libnet/libnet_domain.c index ccdfdaf134..eb6920d88e 100644 --- a/source4/libnet/libnet_domain.c +++ b/source4/libnet/libnet_domain.c @@ -40,6 +40,7 @@ struct domain_open_samr_state { uint32_t access_mask; struct policy_handle connect_handle; struct policy_handle domain_handle; + struct dom_sid2 *domain_sid; /* information about the progress */ void (*monitor_fn)(struct monitor_msg*); @@ -159,6 +160,8 @@ static void continue_domain_open_connect(struct rpc_request *req) /* prepare for samr_LookupDomain call */ r->in.connect_handle = &s->connect_handle; r->in.domain_name = &s->domain_name; + r->out.sid = talloc(s, struct dom_sid2 *); + if (composite_nomem(r->out.sid, c)) return; lookup_req = dcerpc_samr_LookupDomain_send(s->pipe, c, r); if (composite_nomem(lookup_req, c)) return; @@ -209,7 +212,7 @@ static void continue_domain_open_lookup(struct rpc_request *req) /* prepare for samr_OpenDomain call */ r->in.connect_handle = &s->connect_handle; r->in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r->in.sid = s->lookup.out.sid; + r->in.sid = *s->lookup.out.sid; r->out.domain_handle = &s->domain_handle; opendom_req = dcerpc_samr_OpenDomain_send(s->pipe, c, r); @@ -361,7 +364,7 @@ NTSTATUS libnet_DomainOpenSamr_recv(struct composite_context *c, struct libnet_c libnet functions */ ctx->samr.connect_handle = s->connect_handle; ctx->samr.handle = s->domain_handle; - ctx->samr.sid = talloc_steal(ctx, s->lookup.out.sid); + ctx->samr.sid = talloc_steal(ctx, *s->lookup.out.sid); ctx->samr.name = talloc_steal(ctx, s->domain_name.string); ctx->samr.access_mask = s->access_mask; } @@ -998,6 +1001,10 @@ static void continue_samr_connect(struct rpc_request *req) s->enumdom.in.resume_handle = &s->resume_handle; s->enumdom.in.buf_size = s->buf_size; s->enumdom.out.resume_handle = &s->resume_handle; + s->enumdom.out.num_entries = talloc(s, uint32_t); + if (composite_nomem(s->enumdom.out.num_entries, c)) return; + s->enumdom.out.sam = talloc(s, struct samr_SamArray *); + if (composite_nomem(s->enumdom.out.sam, c)) return; enumdom_req = dcerpc_samr_EnumDomains_send(s->ctx->samr.pipe, c, &s->enumdom); if (composite_nomem(enumdom_req, c)) return; @@ -1113,16 +1120,16 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis /* prepare domains array */ if (s->domains == NULL) { s->domains = talloc_array(mem_ctx, struct domainlist, - s->enumdom.out.num_entries); + *s->enumdom.out.num_entries); } else { s->domains = talloc_realloc(mem_ctx, s->domains, struct domainlist, - s->count + s->enumdom.out.num_entries); + s->count + *s->enumdom.out.num_entries); } /* copy domain names returned from samr_EnumDomains call */ - for (i = s->count; i < s->count + s->enumdom.out.num_entries; i++) + for (i = s->count; i < s->count + *s->enumdom.out.num_entries; i++) { - struct lsa_String *domain_name = &s->enumdom.out.sam->entries[i - s->count].name; + struct lsa_String *domain_name = &(*s->enumdom.out.sam)->entries[i - s->count].name; /* strdup name as a child of allocated array to make it follow the array in case of talloc_steal or talloc_free */ @@ -1131,7 +1138,7 @@ static struct domainlist* get_domain_list(TALLOC_CTX *mem_ctx, struct domain_lis } /* number of entries returned (domains enumerated) */ - s->count += s->enumdom.out.num_entries; + s->count += *s->enumdom.out.num_entries; return s->domains; } diff --git a/source4/libnet/libnet_group.c b/source4/libnet/libnet_group.c index eded378511..af5fe4d5d3 100644 --- a/source4/libnet/libnet_group.c +++ b/source4/libnet/libnet_group.c @@ -518,6 +518,10 @@ static void continue_domain_queried(struct rpc_request *req) s->group_list.in.max_size = s->page_size; s->group_list.in.resume_handle = &s->resume_index; s->group_list.out.resume_handle = &s->resume_index; + s->group_list.out.num_entries = talloc(s, uint32_t); + if (composite_nomem(s->group_list.out.num_entries, c)) return; + s->group_list.out.sam = talloc(s, struct samr_SamArray *); + if (composite_nomem(s->group_list.out.sam, c)) return; /* send the request */ enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list); @@ -549,6 +553,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx) s->group_list.in.max_size = s->page_size; s->group_list.in.resume_handle = &s->resume_index; s->group_list.out.resume_handle = &s->resume_index; + s->group_list.out.num_entries = talloc(s, uint32_t); + if (composite_nomem(s->group_list.out.num_entries, c)) return; + s->group_list.out.sam = talloc(s, struct samr_SamArray *); + if (composite_nomem(s->group_list.out.sam, c)) return; /* send the request */ enum_req = dcerpc_samr_EnumDomainGroups_send(s->ctx->samr.pipe, c, &s->group_list); @@ -587,15 +595,15 @@ static void continue_groups_enumerated(struct rpc_request *req) /* get enumerated accounts counter and resume handle (the latter allows making subsequent call to continue enumeration) */ s->resume_index = *s->group_list.out.resume_handle; - s->count = s->group_list.out.num_entries; + s->count = *s->group_list.out.num_entries; /* prepare returned group accounts array */ - s->groups = talloc_array(c, struct grouplist, s->group_list.out.sam->count); + s->groups = talloc_array(c, struct grouplist, (*s->group_list.out.sam)->count); if (composite_nomem(s->groups, c)) return; - for (i = 0; i < s->group_list.out.sam->count; i++) { + for (i = 0; i < (*s->group_list.out.sam)->count; i++) { struct dom_sid *group_sid; - struct samr_SamEntry *entry = &s->group_list.out.sam->entries[i]; + struct samr_SamEntry *entry = &(*s->group_list.out.sam)->entries[i]; struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid; /* construct group sid from returned rid and queried domain sid */ diff --git a/source4/libnet/libnet_join.c b/source4/libnet/libnet_join.c index 0ed5e8ae26..70fcb4a894 100644 --- a/source4/libnet/libnet_join.c +++ b/source4/libnet/libnet_join.c @@ -444,13 +444,16 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru struct samr_OpenDomain od; struct policy_handle d_handle; struct samr_LookupNames ln; + struct samr_Ids rids, types; struct samr_OpenUser ou; struct samr_CreateUser2 cu; struct policy_handle *u_handle = NULL; struct samr_QueryUserInfo qui; + union samr_UserInfo *uinfo; struct samr_UserInfo21 u_info21; union libnet_SetPassword r2; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; struct lsa_String samr_account_name; uint32_t acct_flags, old_acct_flags; @@ -559,9 +562,11 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru if (!connect_with_info->out.domain_sid) { struct lsa_String name; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; name.string = connect_with_info->out.domain_name; l.in.connect_handle = &p_handle; l.in.domain_name = &name; + l.out.sid = &sid; status = dcerpc_samr_LookupDomain(samr_pipe, tmp_ctx, &l); if (!NT_STATUS_IS_OK(status)) { @@ -571,7 +576,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru talloc_free(tmp_ctx); return status; } - connect_with_info->out.domain_sid = l.out.sid; + connect_with_info->out.domain_sid = *l.out.sid; } /* prepare samr_OpenDomain */ @@ -611,6 +616,8 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru ln.in.domain_handle = &d_handle; ln.in.num_names = 1; ln.in.names = talloc_array(tmp_ctx, struct lsa_String, 1); + ln.out.rids = &rids; + ln.out.types = &types; if (!ln.in.names) { r->out.error_string = NULL; talloc_free(tmp_ctx); @@ -630,10 +637,10 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru } /* check if we got one RID for the user */ - if (ln.out.rids.count != 1) { + if (ln.out.rids->count != 1) { r->out.error_string = talloc_asprintf(mem_ctx, "samr_LookupNames for [%s] returns %d RIDs", - r->in.account_name, ln.out.rids.count); + r->in.account_name, ln.out.rids->count); talloc_free(tmp_ctx); return NT_STATUS_INVALID_PARAMETER; } @@ -642,7 +649,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru ZERO_STRUCTP(u_handle); ou.in.domain_handle = &d_handle; ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - ou.in.rid = ln.out.rids.ids[0]; + ou.in.rid = ln.out.rids->ids[0]; rid = ou.in.rid; ou.out.user_handle = u_handle; @@ -694,6 +701,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru /* prepare samr_QueryUserInfo (get flags) */ qui.in.user_handle = u_handle; qui.in.level = 16; + qui.out.info = &uinfo; status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui); if (!NT_STATUS_IS_OK(status)) { @@ -705,7 +713,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - if (!qui.out.info) { + if (!uinfo) { status = NT_STATUS_INVALID_PARAMETER; r->out.error_string = talloc_asprintf(mem_ctx, @@ -715,7 +723,7 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return status; } - old_acct_flags = (qui.out.info->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)); + old_acct_flags = (uinfo->info16.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST | ACB_DOMTRUST)); /* Possibly bail if the account is of the wrong type */ if (old_acct_flags != r->in.acct_type) { @@ -771,17 +779,18 @@ NTSTATUS libnet_JoinDomain(struct libnet_context *ctx, TALLOC_CTX *mem_ctx, stru return NT_STATUS_USER_EXISTS; } } else { - acct_flags = qui.out.info->info16.acct_flags; + acct_flags = uinfo->info16.acct_flags; } acct_flags = (acct_flags & ~(ACB_DISABLED|ACB_PWNOTREQ)); /* Find out what password policy this user has */ pwp.in.user_handle = u_handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(samr_pipe, tmp_ctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } /* Grab a password of that minimum length */ diff --git a/source4/libnet/libnet_passwd.c b/source4/libnet/libnet_passwd.c index de2ed01abd..976606e72c 100644 --- a/source4/libnet/libnet_passwd.c +++ b/source4/libnet/libnet_passwd.c @@ -50,6 +50,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT struct samr_Password nt_verifier, lm_verifier; uint8_t old_nt_hash[16], new_nt_hash[16]; uint8_t old_lm_hash[16], new_lm_hash[16]; + struct samr_DomInfo1 *dominfo = NULL; + struct samr_ChangeReject *reject = NULL; /* prepare connect to the SAMR pipe of the users domain PDC */ c.level = LIBNET_RPC_CONNECT_PDC; @@ -92,6 +94,8 @@ static NTSTATUS libnet_ChangePassword_samr(struct libnet_context *ctx, TALLOC_CT pw3.in.lm_password = &lm_pass; pw3.in.lm_verifier = &lm_verifier; pw3.in.password3 = NULL; + pw3.out.dominfo = &dominfo; + pw3.out.reject = &reject; /* 2. try samr_ChangePasswordUser3 */ status = dcerpc_samr_ChangePasswordUser3(c.out.dcerpc_pipe, mem_ctx, &pw3); @@ -527,10 +531,12 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX * struct samr_Connect sc; struct policy_handle p_handle; struct samr_LookupDomain ld; + struct dom_sid2 *sid = NULL; struct lsa_String d_name; struct samr_OpenDomain od; struct policy_handle d_handle; struct samr_LookupNames ln; + struct samr_Ids rids, types; struct samr_OpenUser ou; struct policy_handle u_handle; union libnet_SetPassword r2; @@ -568,6 +574,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX * d_name.string = r->samr.in.domain_name; ld.in.connect_handle = &p_handle; ld.in.domain_name = &d_name; + ld.out.sid = &sid; /* 3. do a samr_LookupDomain to get the domain sid */ status = dcerpc_samr_LookupDomain(c.out.dcerpc_pipe, mem_ctx, &ld); @@ -582,7 +589,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX * ZERO_STRUCT(d_handle); od.in.connect_handle = &p_handle; od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - od.in.sid = ld.out.sid; + od.in.sid = *ld.out.sid; od.out.domain_handle = &d_handle; /* 4. do a samr_OpenDomain to get a domain handle */ @@ -598,6 +605,8 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX * ln.in.domain_handle = &d_handle; ln.in.num_names = 1; ln.in.names = talloc_array(mem_ctx, struct lsa_String, 1); + ln.out.rids = &rids; + ln.out.types = &types; if (!ln.in.names) { r->samr.out.error_string = "Out of Memory"; return NT_STATUS_NO_MEMORY; @@ -614,10 +623,10 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX * } /* check if we got one RID for the user */ - if (ln.out.rids.count != 1) { + if (ln.out.rids->count != 1) { r->samr.out.error_string = talloc_asprintf(mem_ctx, "samr_LookupNames for [%s] returns %d RIDs", - r->samr.in.account_name, ln.out.rids.count); + r->samr.in.account_name, ln.out.rids->count); status = NT_STATUS_INVALID_PARAMETER; goto disconnect; } @@ -626,7 +635,7 @@ static NTSTATUS libnet_SetPassword_samr(struct libnet_context *ctx, TALLOC_CTX * ZERO_STRUCT(u_handle); ou.in.domain_handle = &d_handle; ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - ou.in.rid = ln.out.rids.ids[0]; + ou.in.rid = ln.out.rids->ids[0]; ou.out.user_handle = &u_handle; /* 6. do a samr_OpenUser to get a user handle */ diff --git a/source4/libnet/libnet_samsync_ldb.c b/source4/libnet/libnet_samsync_ldb.c index 8b7dd1f598..160b4b3e19 100644 --- a/source4/libnet/libnet_samsync_ldb.c +++ b/source4/libnet/libnet_samsync_ldb.c @@ -384,7 +384,11 @@ static NTSTATUS samsync_ldb_handle_user(TALLOC_CTX *mem_ctx, } ADD_OR_DEL(string, "comment", comment.string); - ADD_OR_DEL(string, "userParameters", parameters.string); + + if (samdb_msg_add_parameters(state->sam_ldb, mem_ctx, msg, "userParameters", &user->parameters) != 0) { + return NT_STATUS_NO_MEMORY; + } + ADD_OR_DEL(uint, "countryCode", country_code); ADD_OR_DEL(uint, "codePage", code_page); diff --git a/source4/libnet/libnet_user.c b/source4/libnet/libnet_user.c index c768319452..8606d0856e 100644 --- a/source4/libnet/libnet_user.c +++ b/source4/libnet/libnet_user.c @@ -1032,6 +1032,10 @@ static void continue_domain_queried(struct rpc_request *req) s->user_list.in.resume_handle = &s->resume_index; s->user_list.in.acct_flags = ACB_NORMAL; s->user_list.out.resume_handle = &s->resume_index; + s->user_list.out.num_entries = talloc(s, uint32_t); + if (composite_nomem(s->user_list.out.num_entries, c)) return; + s->user_list.out.sam = talloc(s, struct samr_SamArray *); + if (composite_nomem(s->user_list.out.sam, c)) return; /* send the request */ enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list); @@ -1064,6 +1068,10 @@ static void continue_samr_domain_opened(struct composite_context *ctx) s->user_list.in.resume_handle = &s->resume_index; s->user_list.in.acct_flags = ACB_NORMAL; s->user_list.out.resume_handle = &s->resume_index; + s->user_list.out.sam = talloc(s, struct samr_SamArray *); + if (composite_nomem(s->user_list.out.sam, c)) return; + s->user_list.out.num_entries = talloc(s, uint32_t); + if (composite_nomem(s->user_list.out.num_entries, c)) return; /* send the request */ enum_req = dcerpc_samr_EnumDomainUsers_send(s->ctx->samr.pipe, c, &s->user_list); @@ -1102,15 +1110,15 @@ static void continue_users_enumerated(struct rpc_request *req) /* get enumerated accounts counter and resume handle (the latter allows making subsequent call to continue enumeration) */ s->resume_index = *s->user_list.out.resume_handle; - s->count = s->user_list.out.num_entries; + s->count = *s->user_list.out.num_entries; /* prepare returned user accounts array */ - s->users = talloc_array(c, struct userlist, s->user_list.out.sam->count); + s->users = talloc_array(c, struct userlist, (*s->user_list.out.sam)->count); if (composite_nomem(s->users, c)) return; - for (i = 0; i < s->user_list.out.sam->count; i++) { + for (i = 0; i < (*s->user_list.out.sam)->count; i++) { struct dom_sid *user_sid; - struct samr_SamEntry *entry = &s->user_list.out.sam->entries[i]; + struct samr_SamEntry *entry = &(*s->user_list.out.sam)->entries[i]; struct dom_sid *domain_sid = (*s->query_domain.out.info)->domain.sid; /* construct user sid from returned rid and queried domain sid */ diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c index 37d51d7840..887c3f466c 100644 --- a/source4/libnet/py_net.c +++ b/source4/libnet/py_net.c @@ -24,10 +24,13 @@ #include "lib/events/events.h" #include "param/param.h" +/* FIXME: This prototype should be in param/pyparam.h */ +struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx); + static struct libnet_context *py_net_ctx(PyObject *obj, struct event_context *ev) { /* FIXME: Use obj */ - return libnet_context_init(ev, global_loadparm); + return libnet_context_init(ev, py_default_loadparm_context(NULL)); } static PyObject *py_net_join(PyObject *cls, PyObject *args, PyObject *kwargs) diff --git a/source4/libnet/userinfo.c b/source4/libnet/userinfo.c index e8b6b090c7..710154d41e 100644 --- a/source4/libnet/userinfo.c +++ b/source4/libnet/userinfo.c @@ -82,8 +82,8 @@ static void continue_userinfo_lookup(struct rpc_request *req) if (s->monitor_fn) { msg.type = mon_SamrLookupName; msg_lookup = talloc(s, struct msg_rpc_lookup_name); - msg_lookup->rid = s->lookup.out.rids.ids; - msg_lookup->count = s->lookup.out.rids.count; + msg_lookup->rid = s->lookup.out.rids->ids; + msg_lookup->count = s->lookup.out.rids->count; msg.data = (void*)msg_lookup; msg.data_size = sizeof(*msg_lookup); @@ -93,7 +93,7 @@ static void continue_userinfo_lookup(struct rpc_request *req) /* have we actually got name resolved - we're looking for only one at the moment */ - if (s->lookup.out.rids.count == 0) { + if (s->lookup.out.rids->count == 0) { composite_error(c, NT_STATUS_NO_SUCH_USER); } @@ -102,7 +102,7 @@ static void continue_userinfo_lookup(struct rpc_request *req) /* prepare parameters for LookupNames */ s->openuser.in.domain_handle = &s->domain_handle; s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - s->openuser.in.rid = s->lookup.out.rids.ids[0]; + s->openuser.in.rid = s->lookup.out.rids->ids[0]; s->openuser.out.user_handle = &s->user_handle; /* send request */ @@ -151,6 +151,8 @@ static void continue_userinfo_openuser(struct rpc_request *req) /* prepare parameters for QueryUserInfo call */ s->queryuserinfo.in.user_handle = &s->user_handle; s->queryuserinfo.in.level = s->level; + s->queryuserinfo.out.info = talloc(s, union samr_UserInfo *); + if (composite_nomem(s->queryuserinfo.out.info, c)) return; /* queue rpc call, set event handling and new state */ queryuser_req = dcerpc_samr_QueryUserInfo_send(s->pipe, c, &s->queryuserinfo); @@ -184,7 +186,7 @@ static void continue_userinfo_getuser(struct rpc_request *req) return; } - s->info = talloc_steal(s, s->queryuserinfo.out.info); + s->info = talloc_steal(s, *(s->queryuserinfo.out.info)); /* issue a monitor message */ if (s->monitor_fn) { @@ -297,6 +299,10 @@ struct composite_context *libnet_rpc_userinfo_send(struct dcerpc_pipe *p, s->lookup.in.num_names = 1; s->lookup.in.names = talloc_array(s, struct lsa_String, 1); if (composite_nomem(s->lookup.in.names, c)) return c; + s->lookup.out.rids = talloc_zero(s, struct samr_Ids); + s->lookup.out.types = talloc_zero(s, struct samr_Ids); + if (composite_nomem(s->lookup.out.rids, c)) return c; + if (composite_nomem(s->lookup.out.types, c)) return c; s->lookup.in.names[0].string = talloc_strdup(s, io->in.username); if (composite_nomem(s->lookup.in.names[0].string, c)) return c; diff --git a/source4/libnet/userman.c b/source4/libnet/userman.c index 398d9f2cb0..c638d8af32 100644 --- a/source4/libnet/userman.c +++ b/source4/libnet/userman.c @@ -236,12 +236,12 @@ static void continue_userdel_name_found(struct rpc_request *req) /* what to do when there's no user account to delete and what if there's more than one rid resolved */ - if (!s->lookupname.out.rids.count) { + if (!s->lookupname.out.rids->count) { c->status = NT_STATUS_NO_SUCH_USER; composite_error(c, c->status); return; - } else if (!s->lookupname.out.rids.count > 1) { + } else if (!s->lookupname.out.rids->count > 1) { c->status = NT_STATUS_INVALID_ACCOUNT_NAME; composite_error(c, c->status); return; @@ -251,8 +251,8 @@ static void continue_userdel_name_found(struct rpc_request *req) if (s->monitor_fn) { struct msg_rpc_lookup_name msg_lookup; - msg_lookup.rid = s->lookupname.out.rids.ids; - msg_lookup.count = s->lookupname.out.rids.count; + msg_lookup.rid = s->lookupname.out.rids->ids; + msg_lookup.count = s->lookupname.out.rids->count; msg.type = mon_SamrLookupName; msg.data = (void*)&msg_lookup; @@ -262,7 +262,7 @@ static void continue_userdel_name_found(struct rpc_request *req) /* prepare the arguments for rpc call */ s->openuser.in.domain_handle = &s->domain_handle; - s->openuser.in.rid = s->lookupname.out.rids.ids[0]; + s->openuser.in.rid = s->lookupname.out.rids->ids[0]; s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; s->openuser.out.user_handle = &s->user_handle; @@ -393,6 +393,10 @@ struct composite_context *libnet_rpc_userdel_send(struct dcerpc_pipe *p, s->lookupname.in.num_names = 1; s->lookupname.in.names = talloc_zero(s, struct lsa_String); s->lookupname.in.names->string = io->in.username; + s->lookupname.out.rids = talloc_zero(s, struct samr_Ids); + s->lookupname.out.types = talloc_zero(s, struct samr_Ids); + if (composite_nomem(s->lookupname.out.rids, c)) return c; + if (composite_nomem(s->lookupname.out.types, c)) return c; /* send the request */ lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname); @@ -500,12 +504,12 @@ static void continue_usermod_name_found(struct rpc_request *req) /* what to do when there's no user account to delete and what if there's more than one rid resolved */ - if (!s->lookupname.out.rids.count) { + if (!s->lookupname.out.rids->count) { c->status = NT_STATUS_NO_SUCH_USER; composite_error(c, c->status); return; - } else if (!s->lookupname.out.rids.count > 1) { + } else if (!s->lookupname.out.rids->count > 1) { c->status = NT_STATUS_INVALID_ACCOUNT_NAME; composite_error(c, c->status); return; @@ -515,8 +519,8 @@ static void continue_usermod_name_found(struct rpc_request *req) if (s->monitor_fn) { struct msg_rpc_lookup_name msg_lookup; - msg_lookup.rid = s->lookupname.out.rids.ids; - msg_lookup.count = s->lookupname.out.rids.count; + msg_lookup.rid = s->lookupname.out.rids->ids; + msg_lookup.count = s->lookupname.out.rids->count; msg.type = mon_SamrLookupName; msg.data = (void*)&msg_lookup; @@ -526,7 +530,7 @@ static void continue_usermod_name_found(struct rpc_request *req) /* prepare the next rpc call */ s->openuser.in.domain_handle = &s->domain_handle; - s->openuser.in.rid = s->lookupname.out.rids.ids[0]; + s->openuser.in.rid = s->lookupname.out.rids->ids[0]; s->openuser.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; s->openuser.out.user_handle = &s->user_handle; @@ -679,6 +683,9 @@ static NTSTATUS usermod_change(struct composite_context *c, if (!do_set) { s->queryuser.in.user_handle = &s->user_handle; s->queryuser.in.level = level; + s->queryuser.out.info = talloc(s, union samr_UserInfo *); + if (composite_nomem(s->queryuser.out.info, c)) return; + /* send query user info request to retrieve complete data of a particular info level */ @@ -751,7 +758,7 @@ static void continue_usermod_user_queried(struct rpc_request *req) /* get returned user data and make a change (potentially one of many) */ - s->info = *s->queryuser.out.info; + s->info = *(*s->queryuser.out.info); usermod_setfields(s, &level, i, true); @@ -834,6 +841,10 @@ struct composite_context *libnet_rpc_usermod_send(struct dcerpc_pipe *p, s->lookupname.in.num_names = 1; s->lookupname.in.names = talloc_zero(s, struct lsa_String); s->lookupname.in.names->string = io->in.username; + s->lookupname.out.rids = talloc_zero(s, struct samr_Ids); + s->lookupname.out.types = talloc_zero(s, struct samr_Ids); + if (composite_nomem(s->lookupname.out.rids, c)) return c; + if (composite_nomem(s->lookupname.out.types, c)) return c; /* send the rpc request */ lookup_req = dcerpc_samr_LookupNames_send(p, c, &s->lookupname); diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index b2b9f2e7a7..ba4793cc8e 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -51,7 +51,10 @@ NDR_COMPRESSION_OBJ_FILES = ../librpc/ndr/ndr_compression.o [SUBSYSTEM::NDR_SECURITY] PUBLIC_DEPENDENCIES = NDR_MISC LIBSECURITY -NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o $(ndrsrcdir)/ndr_sec_helper.o +NDR_SECURITY_OBJ_FILES = $(gen_ndrsrcdir)/ndr_security.o \ + ../librpc/ndr/ndr_sec_helper.o \ + $(gen_ndrsrcdir)/ndr_dom_sid.o \ + $(ndrsrcdir)/ndr_dom_sid.o PUBLIC_HEADERS += $(gen_ndrsrcdir)/security.h @@ -60,6 +63,11 @@ PUBLIC_DEPENDENCIES = LIBNDR NDR_AUDIOSRV_OBJ_FILES = $(gen_ndrsrcdir)/ndr_audiosrv.o +[SUBSYSTEM::NDR_NAMED_PIPE_AUTH] +PUBLIC_DEPENDENCIES = LIBNDR + +NDR_NAMED_PIPE_AUTH_OBJ_FILES = $(gen_ndrsrcdir)/ndr_named_pipe_auth.o + [SUBSYSTEM::NDR_DNSSERVER] PUBLIC_DEPENDENCIES = LIBNDR @@ -299,7 +307,7 @@ NDR_NTSVCS_OBJ_FILES = $(gen_ndrsrcdir)/ndr_ntsvcs.o [SUBSYSTEM::NDR_NETLOGON] PUBLIC_DEPENDENCIES = LIBNDR NDR_SAMR NDR_LSA NDR_SECURITY -NDR_NETLOGON_OBJ_FILES = $(gen_ndrsrcdir)/ndr_netlogon.o +NDR_NETLOGON_OBJ_FILES = $(gen_ndrsrcdir)/ndr_netlogon.o ../librpc/ndr/ndr_netlogon.o PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/netlogon.h) @@ -362,7 +370,7 @@ NDR_WINBIND_OBJ_FILES = $(gen_ndrsrcdir)/ndr_winbind.o #PUBLIC_HEADERS += $(gen_ndrsrcdir)/winbind.h $(librpcsrcdir)/idl-deps: - $(PERL) $(librpcsrcdir)/idl-deps.pl $(filter-out ../librpc/idl/security.idl,$(wildcard $(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl)) >$@ + $(PERL) $(librpcsrcdir)/idl-deps.pl $(wildcard $(librpcsrcdir)/idl/*.idl ../librpc/idl/*.idl) >$@ clean:: rm -f $(librpcsrcdir)/idl-deps @@ -386,7 +394,7 @@ PUBLIC_DEPENDENCIES = \ NDR_ROT NDR_DRSBLOBS NDR_SVCCTL NDR_NBT NDR_WINSREPL NDR_SECURITY \ NDR_INITSHUTDOWN NDR_DNSSERVER NDR_WINSTATION NDR_IRPC NDR_OPENDB \ NDR_SASL_HELPERS NDR_NOTIFY NDR_WINBIND NDR_FRSRPC NDR_FRSAPI NDR_NFS4ACL NDR_NTP_SIGND \ - NDR_DCOM NDR_WMI + NDR_DCOM NDR_WMI NDR_NAMED_PIPE_AUTH NDR_TABLE_OBJ_FILES = ../librpc/ndr/ndr_table.o $(gen_ndrsrcdir)/tables.o @@ -729,9 +737,15 @@ PRIVATE_DEPENDENCIES = RPC_NDR_DRSUAPI PYTALLOC param swig_credentials python_dc python_drsuapi_OBJ_FILES = $(gen_ndrsrcdir)/py_drsuapi.o +[PYTHON::python_dcerpc_dom_sid] +LIBRARY_REALNAME = samba/dcerpc/dom_sid.$(SHLIBEXT) +PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc + +python_dcerpc_dom_sid_OBJ_FILES = $(gen_ndrsrcdir)/py_dom_sid.o + [PYTHON::python_dcerpc_security] LIBRARY_REALNAME = samba/dcerpc/security.$(SHLIBEXT) -PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc +PRIVATE_DEPENDENCIES = PYTALLOC python_dcerpc_misc python_dcerpc_dom_sid python_dcerpc python_dcerpc_security_OBJ_FILES = $(gen_ndrsrcdir)/py_security.o diff --git a/source4/librpc/idl/dom_sid.idl b/source4/librpc/idl/dom_sid.idl new file mode 100644 index 0000000000..80df11dbfe --- /dev/null +++ b/source4/librpc/idl/dom_sid.idl @@ -0,0 +1,42 @@ +/* + use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really + just a dom sid, but with the sub_auths represented as a conformant + array. As with all in-structure conformant arrays, the array length + is placed before the start of the structure. That's what gives rise + to the extra num_auths elemenent. We don't want the Samba code to + have to bother with such esoteric NDR details, so its easier to just + define it as a dom_sid and use pidl magic to make it all work. It + just means you need to mark a sid as a "dom_sid2" in the IDL when you + know it is of the conformant array variety +*/ +cpp_quote("#define dom_sid2 dom_sid") + +/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ +cpp_quote("#define dom_sid28 dom_sid") + +/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */ +cpp_quote("#define dom_sid0 dom_sid") + +[ + pointer_default(unique) +] +interface dom_sid +{ + /* a domain SID. Note that unlike Samba3 this contains a pointer, + so you can't copy them using assignment */ + typedef [public,gensize,noprint,noejs,nosize] struct { + uint8 sid_rev_num; /**< SID revision number */ + [range(0,15)] int8 num_auths; /**< Number of sub-authorities */ + uint8 id_auth[6]; /**< Identifier Authority */ + uint32 sub_auths[num_auths]; + } dom_sid; + + /* id used to identify a endpoint, possibly in a cluster */ + typedef [public] struct { + hyper id; + uint32 id2; + uint32 node; + } server_id; + +} + diff --git a/source4/librpc/idl/samr.idl b/source4/librpc/idl/samr.idl deleted file mode 100644 index 47882dfb84..0000000000 --- a/source4/librpc/idl/samr.idl +++ /dev/null @@ -1,1424 +0,0 @@ -#include "idl_types.h" - -/* - samr interface definition -*/ -import "misc.idl", "lsa.idl", "security.idl"; - -/* - Thanks to Todd Sabin for some information from his samr.idl in acltools -*/ - -[ uuid("12345778-1234-abcd-ef00-0123456789ac"), - version(1.0), - endpoint("ncacn_np:[\\pipe\\samr]","ncacn_ip_tcp:", "ncalrpc:"), - pointer_default(unique) -] interface samr -{ - typedef bitmap security_secinfo security_secinfo; - - /* account control (acct_flags) bits */ - typedef [public,bitmap32bit] bitmap { - ACB_DISABLED = 0x00000001, /* 1 = User account disabled */ - ACB_HOMDIRREQ = 0x00000002, /* 1 = Home directory required */ - ACB_PWNOTREQ = 0x00000004, /* 1 = User password not required */ - ACB_TEMPDUP = 0x00000008, /* 1 = Temporary duplicate account */ - ACB_NORMAL = 0x00000010, /* 1 = Normal user account */ - ACB_MNS = 0x00000020, /* 1 = MNS logon user account */ - ACB_DOMTRUST = 0x00000040, /* 1 = Interdomain trust account */ - ACB_WSTRUST = 0x00000080, /* 1 = Workstation trust account */ - ACB_SVRTRUST = 0x00000100, /* 1 = Server trust account */ - ACB_PWNOEXP = 0x00000200, /* 1 = User password does not expire */ - ACB_AUTOLOCK = 0x00000400, /* 1 = Account auto locked */ - ACB_ENC_TXT_PWD_ALLOWED = 0x00000800, /* 1 = Encryped text password is allowed */ - ACB_SMARTCARD_REQUIRED = 0x00001000, /* 1 = Smart Card required */ - ACB_TRUSTED_FOR_DELEGATION = 0x00002000, /* 1 = Trusted for Delegation */ - ACB_NOT_DELEGATED = 0x00004000, /* 1 = Not delegated */ - ACB_USE_DES_KEY_ONLY = 0x00008000, /* 1 = Use DES key only */ - ACB_DONT_REQUIRE_PREAUTH = 0x00010000, /* 1 = Preauth not required */ - ACB_PW_EXPIRED = 0x00020000, /* 1 = Password Expired */ - ACB_NO_AUTH_DATA_REQD = 0x00080000 /* 1 = No authorization data required */ - } samr_AcctFlags; - - typedef [bitmap32bit] bitmap { - SAMR_ACCESS_CONNECT_TO_SERVER = 0x00000001, - SAMR_ACCESS_SHUTDOWN_SERVER = 0x00000002, - SAMR_ACCESS_INITIALIZE_SERVER = 0x00000004, - SAMR_ACCESS_CREATE_DOMAIN = 0x00000008, - SAMR_ACCESS_ENUM_DOMAINS = 0x00000010, - SAMR_ACCESS_OPEN_DOMAIN = 0x00000020 - } samr_ConnectAccessMask; - - typedef [bitmap32bit] bitmap { - SAMR_USER_ACCESS_GET_NAME_ETC = 0x00000001, - SAMR_USER_ACCESS_GET_LOCALE = 0x00000002, - SAMR_USER_ACCESS_SET_LOC_COM = 0x00000004, - SAMR_USER_ACCESS_GET_LOGONINFO = 0x00000008, - SAMR_USER_ACCESS_GET_ATTRIBUTES = 0x00000010, - SAMR_USER_ACCESS_SET_ATTRIBUTES = 0x00000020, - SAMR_USER_ACCESS_CHANGE_PASSWORD = 0x00000040, - SAMR_USER_ACCESS_SET_PASSWORD = 0x00000080, - SAMR_USER_ACCESS_GET_GROUPS = 0x00000100, - SAMR_USER_ACCESS_GET_GROUP_MEMBERSHIP = 0x00000200, - SAMR_USER_ACCESS_CHANGE_GROUP_MEMBERSHIP = 0x00000400 - } samr_UserAccessMask; - - typedef [bitmap32bit] bitmap { - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_1 = 0x00000001, - SAMR_DOMAIN_ACCESS_SET_INFO_1 = 0x00000002, - SAMR_DOMAIN_ACCESS_LOOKUP_INFO_2 = 0x00000004, - SAMR_DOMAIN_ACCESS_SET_INFO_2 = 0x00000008, - SAMR_DOMAIN_ACCESS_CREATE_USER = 0x00000010, - SAMR_DOMAIN_ACCESS_CREATE_GROUP = 0x00000020, - SAMR_DOMAIN_ACCESS_CREATE_ALIAS = 0x00000040, - SAMR_DOMAIN_ACCESS_LOOKUP_ALIAS = 0x00000080, - SAMR_DOMAIN_ACCESS_ENUM_ACCOUNTS = 0x00000100, - SAMR_DOMAIN_ACCESS_OPEN_ACCOUNT = 0x00000200, - SAMR_DOMAIN_ACCESS_SET_INFO_3 = 0x00000400 - } samr_DomainAccessMask; - - typedef [bitmap32bit] bitmap { - SAMR_GROUP_ACCESS_LOOKUP_INFO = 0x00000001, - SAMR_GROUP_ACCESS_SET_INFO = 0x00000002, - SAMR_GROUP_ACCESS_ADD_MEMBER = 0x00000004, - SAMR_GROUP_ACCESS_REMOVE_MEMBER = 0x00000008, - SAMR_GROUP_ACCESS_GET_MEMBERS = 0x00000010 - } samr_GroupAccessMask; - - typedef [bitmap32bit] bitmap { - SAMR_ALIAS_ACCESS_ADD_MEMBER = 0x00000001, - SAMR_ALIAS_ACCESS_REMOVE_MEMBER = 0x00000002, - SAMR_ALIAS_ACCESS_GET_MEMBERS = 0x00000004, - SAMR_ALIAS_ACCESS_LOOKUP_INFO = 0x00000008, - SAMR_ALIAS_ACCESS_SET_INFO = 0x00000010 - } samr_AliasAccessMask; - - /******************/ - /* Function: 0x00 */ - NTSTATUS samr_Connect ( - /* notice the lack of [string] */ - [in,unique] uint16 *system_name, - [in] samr_ConnectAccessMask access_mask, - [out,ref] policy_handle *connect_handle - ); - - - /******************/ - /* Function: 0x01 */ - [public] NTSTATUS samr_Close ( - [in,out,ref] policy_handle *handle - ); - - /******************/ - /* Function: 0x02 */ - - NTSTATUS samr_SetSecurity ( - [in,ref] policy_handle *handle, - [in] security_secinfo sec_info, - [in,ref] sec_desc_buf *sdbuf - ); - - /******************/ - /* Function: 0x03 */ - - NTSTATUS samr_QuerySecurity ( - [in,ref] policy_handle *handle, - [in] security_secinfo sec_info, - [out,unique] sec_desc_buf *sdbuf - ); - - /******************/ - /* Function: 0x04 */ - - /* - shutdown the SAM - once you call this the SAM will be dead - */ - NTSTATUS samr_Shutdown ( - [in,ref] policy_handle *connect_handle - ); - - /******************/ - /* Function: 0x05 */ - NTSTATUS samr_LookupDomain ( - [in,ref] policy_handle *connect_handle, - [in,ref] lsa_String *domain_name, - [out,unique] dom_sid2 *sid - ); - - - /******************/ - /* Function: 0x06 */ - - typedef struct { - uint32 idx; - lsa_String name; - } samr_SamEntry; - - typedef struct { - uint32 count; - [size_is(count)] samr_SamEntry *entries; - } samr_SamArray; - - NTSTATUS samr_EnumDomains ( - [in,ref] policy_handle *connect_handle, - [in,out,ref] uint32 *resume_handle, - [in] uint32 buf_size, - [out,unique] samr_SamArray *sam, - [out] uint32 num_entries - ); - - - /************************/ - /* Function 0x07 */ - [public] NTSTATUS samr_OpenDomain( - [in,ref] policy_handle *connect_handle, - [in] samr_DomainAccessMask access_mask, - [in,ref] dom_sid2 *sid, - [out,ref] policy_handle *domain_handle - ); - - /************************/ - /* Function 0x08 */ - /* server roles */ - typedef [v1_enum] enum { - SAMR_ROLE_STANDALONE = 0, - SAMR_ROLE_DOMAIN_MEMBER = 1, - SAMR_ROLE_DOMAIN_BDC = 2, - SAMR_ROLE_DOMAIN_PDC = 3 - } samr_Role; - - /* password properties flags */ - typedef [public,bitmap32bit] bitmap { - DOMAIN_PASSWORD_COMPLEX = 0x00000001, - DOMAIN_PASSWORD_NO_ANON_CHANGE = 0x00000002, - DOMAIN_PASSWORD_NO_CLEAR_CHANGE = 0x00000004, - DOMAIN_PASSWORD_LOCKOUT_ADMINS = 0x00000008, - DOMAIN_PASSWORD_STORE_CLEARTEXT = 0x00000010, - DOMAIN_REFUSE_PASSWORD_CHANGE = 0x00000020 - } samr_PasswordProperties; - - typedef struct { - uint16 min_password_length; - uint16 password_history_length; - samr_PasswordProperties password_properties; - /* yes, these are signed. They are in negative 100ns */ - dlong max_password_age; - dlong min_password_age; - } samr_DomInfo1; - - typedef struct { - NTTIME force_logoff_time; - lsa_String oem_information; /* comment */ - lsa_String domain_name; - lsa_String primary; /* PDC name if this is a BDC */ - udlong sequence_num; - uint32 unknown2; - samr_Role role; - uint32 unknown3; - uint32 num_users; - uint32 num_groups; - uint32 num_aliases; - } samr_DomGeneralInformation; - - typedef struct { - NTTIME force_logoff_time; - } samr_DomInfo3; - - typedef struct { - lsa_String oem_information; /* comment */ - } samr_DomOEMInformation; - - typedef struct { - lsa_String domain_name; - } samr_DomInfo5; - - typedef struct { - lsa_String primary; - } samr_DomInfo6; - - typedef struct { - samr_Role role; - } samr_DomInfo7; - - typedef struct { - hyper sequence_num; - NTTIME domain_create_time; - } samr_DomInfo8; - - typedef struct { - uint32 unknown; /* w2k3 returns 1 */ - } samr_DomInfo9; - - typedef struct { - samr_DomGeneralInformation general; - hyper lockout_duration; - hyper lockout_window; - uint16 lockout_threshold; - } samr_DomGeneralInformation2; - - typedef struct { - hyper lockout_duration; - hyper lockout_window; - uint16 lockout_threshold; - } samr_DomInfo12; - - typedef struct { - hyper sequence_num; - NTTIME domain_create_time; - uint32 unknown1; - uint32 unknown2; - } samr_DomInfo13; - - typedef [switch_type(uint16)] union { - [case(1)] samr_DomInfo1 info1; - [case(2)] samr_DomGeneralInformation general; - [case(3)] samr_DomInfo3 info3; - [case(4)] samr_DomOEMInformation oem; - [case(5)] samr_DomInfo5 info5; - [case(6)] samr_DomInfo6 info6; - [case(7)] samr_DomInfo7 info7; - [case(8)] samr_DomInfo8 info8; - [case(9)] samr_DomInfo9 info9; - [case(11)] samr_DomGeneralInformation2 general2; - [case(12)] samr_DomInfo12 info12; - [case(13)] samr_DomInfo13 info13; - } samr_DomainInfo; - - NTSTATUS samr_QueryDomainInfo( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [out,switch_is(level),unique] samr_DomainInfo *info - ); - - /************************/ - /* Function 0x09 */ - /* - only levels 1, 3, 4, 6, 7, 9, 12 are valid for this - call in w2k3 - */ - NTSTATUS samr_SetDomainInfo( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [in,switch_is(level),ref] samr_DomainInfo *info - ); - - - /************************/ - /* Function 0x0a */ - NTSTATUS samr_CreateDomainGroup( - [in,ref] policy_handle *domain_handle, - [in,ref] lsa_String *name, - [in] samr_GroupAccessMask access_mask, - [out,ref] policy_handle *group_handle, - [out,ref] uint32 *rid - ); - - - /************************/ - /* Function 0x0b */ - NTSTATUS samr_EnumDomainGroups( - [in,ref] policy_handle *domain_handle, - [in,out,ref] uint32 *resume_handle, - [in] uint32 max_size, - [out,unique] samr_SamArray *sam, - [out] uint32 num_entries - ); - - /************************/ - /* Function 0x0c */ - NTSTATUS samr_CreateUser( - [in,ref] policy_handle *domain_handle, - [in,ref] lsa_String *account_name, - [in] samr_UserAccessMask access_mask, - [out,ref] policy_handle *user_handle, - [out,ref] uint32 *rid - ); - - /************************/ - /* Function 0x0d */ - - - /* w2k3 treats max_size as max_users*54 and sets the - resume_handle as the rid of the last user sent - */ - const int SAMR_ENUM_USERS_MULTIPLIER = 54; - - NTSTATUS samr_EnumDomainUsers( - [in,ref] policy_handle *domain_handle, - [in,out,ref] uint32 *resume_handle, - [in] samr_AcctFlags acct_flags, - [in] uint32 max_size, - [out,unique] samr_SamArray *sam, - [out] uint32 num_entries - ); - - /************************/ - /* Function 0x0e */ - NTSTATUS samr_CreateDomAlias( - [in,ref] policy_handle *domain_handle, - [in,ref] lsa_String *alias_name, - [in] samr_AliasAccessMask access_mask, - [out,ref] policy_handle *alias_handle, - [out,ref] uint32 *rid - ); - - /************************/ - /* Function 0x0f */ - NTSTATUS samr_EnumDomainAliases( - [in,ref] policy_handle *domain_handle, - [in,out,ref] uint32 *resume_handle, - [in] samr_AcctFlags acct_flags, - [out,unique] samr_SamArray *sam, - [out] uint32 num_entries - ); - - /************************/ - /* Function 0x10 */ - - typedef struct { - [range(0,1024)] uint32 count; - [size_is(count)] uint32 *ids; - } samr_Ids; - - NTSTATUS samr_GetAliasMembership( - [in,ref] policy_handle *domain_handle, - [in,ref] lsa_SidArray *sids, - [out,ref] samr_Ids *rids - ); - - /************************/ - /* Function 0x11 */ - - [public] NTSTATUS samr_LookupNames( - [in,ref] policy_handle *domain_handle, - [in,range(0,1000)] uint32 num_names, - [in,size_is(1000),length_is(num_names)] lsa_String names[], - [out] samr_Ids rids, - [out] samr_Ids types - ); - - - /************************/ - /* Function 0x12 */ - NTSTATUS samr_LookupRids( - [in,ref] policy_handle *domain_handle, - [in,range(0,1000)] uint32 num_rids, - [in,size_is(1000),length_is(num_rids)] uint32 rids[], - [out] lsa_Strings names, - [out] samr_Ids types - ); - - /************************/ - /* Function 0x13 */ - NTSTATUS samr_OpenGroup( - [in,ref] policy_handle *domain_handle, - [in] samr_GroupAccessMask access_mask, - [in] uint32 rid, - [out,ref] policy_handle *group_handle - ); - - /* Group attributes */ - typedef [public,bitmap32bit] bitmap { - SE_GROUP_MANDATORY = 0x00000001, - SE_GROUP_ENABLED_BY_DEFAULT = 0x00000002, - SE_GROUP_ENABLED = 0x00000004, - SE_GROUP_OWNER = 0x00000008, - SE_GROUP_USE_FOR_DENY_ONLY = 0x00000010, - SE_GROUP_RESOURCE = 0x20000000, - SE_GROUP_LOGON_ID = 0xC0000000 - } samr_GroupAttrs; - - /************************/ - /* Function 0x14 */ - - typedef struct { - lsa_String name; - samr_GroupAttrs attributes; - uint32 num_members; - lsa_String description; - } samr_GroupInfoAll; - - typedef struct { - samr_GroupAttrs attributes; - } samr_GroupInfoAttributes; - - typedef struct { - lsa_String description; - } samr_GroupInfoDescription; - - typedef enum { - GROUPINFOALL = 1, - GROUPINFONAME = 2, - GROUPINFOATTRIBUTES = 3, - GROUPINFODESCRIPTION = 4, - GROUPINFOALL2 = 5 - } samr_GroupInfoEnum; - - typedef [switch_type(samr_GroupInfoEnum)] union { - [case(GROUPINFOALL)] samr_GroupInfoAll all; - [case(GROUPINFONAME)] lsa_String name; - [case(GROUPINFOATTRIBUTES)] samr_GroupInfoAttributes attributes; - [case(GROUPINFODESCRIPTION)] lsa_String description; - [case(GROUPINFOALL2)] samr_GroupInfoAll all2; - } samr_GroupInfo; - - NTSTATUS samr_QueryGroupInfo( - [in,ref] policy_handle *group_handle, - [in] samr_GroupInfoEnum level, - [out,switch_is(level),unique] samr_GroupInfo *info - ); - - /************************/ - /* Function 0x15 */ - NTSTATUS samr_SetGroupInfo( - [in,ref] policy_handle *group_handle, - [in] samr_GroupInfoEnum level, - [in,switch_is(level),ref] samr_GroupInfo *info - ); - - /************************/ - /* Function 0x16 */ - NTSTATUS samr_AddGroupMember( - [in,ref] policy_handle *group_handle, - [in] uint32 rid, - [in] uint32 flags - ); - - /************************/ - /* Function 0x17 */ - NTSTATUS samr_DeleteDomainGroup( - [in,out,ref] policy_handle *group_handle - ); - - /************************/ - /* Function 0x18 */ - NTSTATUS samr_DeleteGroupMember( - [in,ref] policy_handle *group_handle, - [in] uint32 rid - ); - - - /************************/ - /* Function 0x19 */ - typedef struct { - uint32 count; - [size_is(count)] uint32 *rids; - [size_is(count)] uint32 *types; - } samr_RidTypeArray; - - NTSTATUS samr_QueryGroupMember( - [in,ref] policy_handle *group_handle, - [out,unique] samr_RidTypeArray *rids - ); - - - /************************/ - /* Function 0x1a */ - - /* - win2003 seems to accept any data at all for the two integers - below, and doesn't seem to do anything with them that I can - see. Weird. I really expected the first integer to be a rid - and the second to be the attributes for that rid member. - */ - NTSTATUS samr_SetMemberAttributesOfGroup( - [in,ref] policy_handle *group_handle, - [in] uint32 unknown1, - [in] uint32 unknown2 - ); - - - /************************/ - /* Function 0x1b */ - NTSTATUS samr_OpenAlias ( - [in,ref] policy_handle *domain_handle, - [in] samr_AliasAccessMask access_mask, - [in] uint32 rid, - [out,ref] policy_handle *alias_handle - ); - - - /************************/ - /* Function 0x1c */ - - typedef struct { - lsa_String name; - uint32 num_members; - lsa_String description; - } samr_AliasInfoAll; - - typedef enum { - ALIASINFOALL = 1, - ALIASINFONAME = 2, - ALIASINFODESCRIPTION = 3 - } samr_AliasInfoEnum; - - typedef [switch_type(samr_AliasInfoEnum)] union { - [case(ALIASINFOALL)] samr_AliasInfoAll all; - [case(ALIASINFONAME)] lsa_String name; - [case(ALIASINFODESCRIPTION)] lsa_String description; - } samr_AliasInfo; - - NTSTATUS samr_QueryAliasInfo( - [in,ref] policy_handle *alias_handle, - [in] samr_AliasInfoEnum level, - [out,switch_is(level),unique] samr_AliasInfo *info - ); - - /************************/ - /* Function 0x1d */ - NTSTATUS samr_SetAliasInfo( - [in,ref] policy_handle *alias_handle, - [in] samr_AliasInfoEnum level, - [in,switch_is(level),ref] samr_AliasInfo *info - ); - - /************************/ - /* Function 0x1e */ - NTSTATUS samr_DeleteDomAlias( - [in,out,ref] policy_handle *alias_handle - ); - - /************************/ - /* Function 0x1f */ - NTSTATUS samr_AddAliasMember( - [in,ref] policy_handle *alias_handle, - [in,ref] dom_sid2 *sid - ); - - /************************/ - /* Function 0x20 */ - NTSTATUS samr_DeleteAliasMember( - [in,ref] policy_handle *alias_handle, - [in,ref] dom_sid2 *sid - ); - - /************************/ - /* Function 0x21 */ - NTSTATUS samr_GetMembersInAlias( - [in,ref] policy_handle *alias_handle, - [out,ref] lsa_SidArray *sids - ); - - /************************/ - /* Function 0x22 */ - [public] NTSTATUS samr_OpenUser( - [in,ref] policy_handle *domain_handle, - [in] samr_UserAccessMask access_mask, - [in] uint32 rid, - [out,ref] policy_handle *user_handle - ); - - /************************/ - /* Function 0x23 */ - NTSTATUS samr_DeleteUser( - [in,out,ref] policy_handle *user_handle - ); - - /************************/ - /* Function 0x24 */ - typedef struct { - lsa_String account_name; - lsa_String full_name; - uint32 primary_gid; - lsa_String description; - lsa_String comment; - } samr_UserInfo1; - - typedef struct { - lsa_String comment; - lsa_String unknown; /* settable, but doesn't stick. probably obsolete */ - uint16 country_code; - uint16 code_page; - } samr_UserInfo2; - - /* this is also used in samr and netlogon */ - typedef [public, flag(NDR_PAHEX)] struct { - uint16 units_per_week; - [size_is(1260), length_is(units_per_week/8)] uint8 *bits; - } samr_LogonHours; - - typedef struct { - lsa_String account_name; - lsa_String full_name; - uint32 rid; - uint32 primary_gid; - lsa_String home_directory; - lsa_String home_drive; - lsa_String logon_script; - lsa_String profile_path; - lsa_String workstations; - NTTIME last_logon; - NTTIME last_logoff; - NTTIME last_password_change; - NTTIME allow_password_change; - NTTIME force_password_change; - samr_LogonHours logon_hours; - uint16 bad_password_count; - uint16 logon_count; - samr_AcctFlags acct_flags; - } samr_UserInfo3; - - typedef struct { - samr_LogonHours logon_hours; - } samr_UserInfo4; - - typedef struct { - lsa_String account_name; - lsa_String full_name; - uint32 rid; - uint32 primary_gid; - lsa_String home_directory; - lsa_String home_drive; - lsa_String logon_script; - lsa_String profile_path; - lsa_String description; - lsa_String workstations; - NTTIME last_logon; - NTTIME last_logoff; - samr_LogonHours logon_hours; - uint16 bad_password_count; - uint16 logon_count; - NTTIME last_password_change; - NTTIME acct_expiry; - samr_AcctFlags acct_flags; - } samr_UserInfo5; - - typedef struct { - lsa_String account_name; - lsa_String full_name; - } samr_UserInfo6; - - typedef struct { - lsa_String account_name; - } samr_UserInfo7; - - typedef struct { - lsa_String full_name; - } samr_UserInfo8; - - typedef struct { - uint32 primary_gid; - } samr_UserInfo9; - - typedef struct { - lsa_String home_directory; - lsa_String home_drive; - } samr_UserInfo10; - - typedef struct { - lsa_String logon_script; - } samr_UserInfo11; - - typedef struct { - lsa_String profile_path; - } samr_UserInfo12; - - typedef struct { - lsa_String description; - } samr_UserInfo13; - - typedef struct { - lsa_String workstations; - } samr_UserInfo14; - - typedef struct { - samr_AcctFlags acct_flags; - } samr_UserInfo16; - - typedef struct { - NTTIME acct_expiry; - } samr_UserInfo17; - - typedef [public, flag(NDR_PAHEX)] struct { - uint8 hash[16]; - } samr_Password; - - typedef struct { - samr_Password lm_pwd; - samr_Password nt_pwd; - boolean8 lm_pwd_active; - boolean8 nt_pwd_active; - } samr_UserInfo18; - - typedef struct { - lsa_String parameters; - } samr_UserInfo20; - - /* this defines the bits used for fields_present in info21 */ - typedef [bitmap32bit] bitmap { - SAMR_FIELD_ACCOUNT_NAME = 0x00000001, - SAMR_FIELD_FULL_NAME = 0x00000002, - SAMR_FIELD_RID = 0x00000004, - SAMR_FIELD_PRIMARY_GID = 0x00000008, - SAMR_FIELD_DESCRIPTION = 0x00000010, - SAMR_FIELD_COMMENT = 0x00000020, - SAMR_FIELD_HOME_DIRECTORY = 0x00000040, - SAMR_FIELD_HOME_DRIVE = 0x00000080, - SAMR_FIELD_LOGON_SCRIPT = 0x00000100, - SAMR_FIELD_PROFILE_PATH = 0x00000200, - SAMR_FIELD_WORKSTATIONS = 0x00000400, - SAMR_FIELD_LAST_LOGON = 0x00000800, - SAMR_FIELD_LAST_LOGOFF = 0x00001000, - SAMR_FIELD_LOGON_HOURS = 0x00002000, - SAMR_FIELD_BAD_PWD_COUNT = 0x00004000, - SAMR_FIELD_NUM_LOGONS = 0x00008000, - SAMR_FIELD_ALLOW_PWD_CHANGE = 0x00010000, - SAMR_FIELD_FORCE_PWD_CHANGE = 0x00020000, - SAMR_FIELD_LAST_PWD_CHANGE = 0x00040000, - SAMR_FIELD_ACCT_EXPIRY = 0x00080000, - SAMR_FIELD_ACCT_FLAGS = 0x00100000, - SAMR_FIELD_PARAMETERS = 0x00200000, - SAMR_FIELD_COUNTRY_CODE = 0x00400000, - SAMR_FIELD_CODE_PAGE = 0x00800000, - SAMR_FIELD_PASSWORD = 0x01000000, /* either of these */ - SAMR_FIELD_PASSWORD2 = 0x02000000, /* two bits seems to work */ - SAMR_FIELD_PRIVATE_DATA = 0x04000000, - SAMR_FIELD_EXPIRED_FLAG = 0x08000000, - SAMR_FIELD_SEC_DESC = 0x10000000, - SAMR_FIELD_OWF_PWD = 0x20000000 - } samr_FieldsPresent; - - /* used for 'password_expired' in samr_UserInfo21 */ - const int PASS_MUST_CHANGE_AT_NEXT_LOGON = 0x01; - const int PASS_DONT_CHANGE_AT_NEXT_LOGON = 0x00; - - typedef struct { - NTTIME last_logon; - NTTIME last_logoff; - NTTIME last_password_change; - NTTIME acct_expiry; - NTTIME allow_password_change; - NTTIME force_password_change; - lsa_String account_name; - lsa_String full_name; - lsa_String home_directory; - lsa_String home_drive; - lsa_String logon_script; - lsa_String profile_path; - lsa_String description; - lsa_String workstations; - lsa_String comment; - lsa_String parameters; - lsa_String unknown1; - lsa_String unknown2; - lsa_String unknown3; - uint32 buf_count; - [size_is(buf_count)] uint8 *buffer; - uint32 rid; - uint32 primary_gid; - samr_AcctFlags acct_flags; - samr_FieldsPresent fields_present; - samr_LogonHours logon_hours; - uint16 bad_password_count; - uint16 logon_count; - uint16 country_code; - uint16 code_page; - uint8 nt_password_set; - uint8 lm_password_set; - uint8 password_expired; - uint8 unknown4; - } samr_UserInfo21; - - typedef [public, flag(NDR_PAHEX)] struct { - uint8 data[516]; - } samr_CryptPassword; - - typedef struct { - samr_UserInfo21 info; - samr_CryptPassword password; - } samr_UserInfo23; - - typedef struct { - samr_CryptPassword password; - uint8 pw_len; - } samr_UserInfo24; - - typedef [flag(NDR_PAHEX)] struct { - uint8 data[532]; - } samr_CryptPasswordEx; - - typedef struct { - samr_UserInfo21 info; - samr_CryptPasswordEx password; - } samr_UserInfo25; - - typedef struct { - samr_CryptPasswordEx password; - uint8 pw_len; - } samr_UserInfo26; - - typedef [switch_type(uint16)] union { - [case(1)] samr_UserInfo1 info1; - [case(2)] samr_UserInfo2 info2; - [case(3)] samr_UserInfo3 info3; - [case(4)] samr_UserInfo4 info4; - [case(5)] samr_UserInfo5 info5; - [case(6)] samr_UserInfo6 info6; - [case(7)] samr_UserInfo7 info7; - [case(8)] samr_UserInfo8 info8; - [case(9)] samr_UserInfo9 info9; - [case(10)] samr_UserInfo10 info10; - [case(11)] samr_UserInfo11 info11; - [case(12)] samr_UserInfo12 info12; - [case(13)] samr_UserInfo13 info13; - [case(14)] samr_UserInfo14 info14; - [case(16)] samr_UserInfo16 info16; - [case(17)] samr_UserInfo17 info17; - [case(18)] samr_UserInfo18 info18; - [case(20)] samr_UserInfo20 info20; - [case(21)] samr_UserInfo21 info21; - [case(23)] samr_UserInfo23 info23; - [case(24)] samr_UserInfo24 info24; - [case(25)] samr_UserInfo25 info25; - [case(26)] samr_UserInfo26 info26; - } samr_UserInfo; - - [public] NTSTATUS samr_QueryUserInfo( - [in,ref] policy_handle *user_handle, - [in] uint16 level, - [out,unique,switch_is(level)] samr_UserInfo *info - ); - - - /************************/ - /* Function 0x25 */ - [public] NTSTATUS samr_SetUserInfo( - [in,ref] policy_handle *user_handle, - [in] uint16 level, - [in,ref,switch_is(level)] samr_UserInfo *info - ); - - /************************/ - /* Function 0x26 */ - /* - this is a password change interface that doesn't give - the server the plaintext password. Depricated. - */ - NTSTATUS samr_ChangePasswordUser( - [in,ref] policy_handle *user_handle, - [in] boolean8 lm_present, - [in,unique] samr_Password *old_lm_crypted, - [in,unique] samr_Password *new_lm_crypted, - [in] boolean8 nt_present, - [in,unique] samr_Password *old_nt_crypted, - [in,unique] samr_Password *new_nt_crypted, - [in] boolean8 cross1_present, - [in,unique] samr_Password *nt_cross, - [in] boolean8 cross2_present, - [in,unique] samr_Password *lm_cross - ); - - /************************/ - /* Function 0x27 */ - - typedef [public] struct { - uint32 rid; - samr_GroupAttrs attributes; - } samr_RidWithAttribute; - - typedef [public] struct { - uint32 count; - [size_is(count)] samr_RidWithAttribute *rids; - } samr_RidWithAttributeArray; - - NTSTATUS samr_GetGroupsForUser( - [in,ref] policy_handle *user_handle, - [out,unique] samr_RidWithAttributeArray *rids - ); - - /************************/ - /* Function 0x28 */ - - typedef struct { - uint32 idx; - uint32 rid; - samr_AcctFlags acct_flags; - lsa_String account_name; - lsa_String description; - lsa_String full_name; - } samr_DispEntryGeneral; - - typedef struct { - uint32 count; - [size_is(count)] samr_DispEntryGeneral *entries; - } samr_DispInfoGeneral; - - typedef struct { - uint32 idx; - uint32 rid; - samr_AcctFlags acct_flags; - lsa_String account_name; - lsa_String description; - } samr_DispEntryFull; - - typedef struct { - uint32 count; - [size_is(count)] samr_DispEntryFull *entries; - } samr_DispInfoFull; - - typedef struct { - uint32 idx; - uint32 rid; - samr_GroupAttrs acct_flags; - lsa_String account_name; - lsa_String description; - } samr_DispEntryFullGroup; - - typedef struct { - uint32 count; - [size_is(count)] samr_DispEntryFullGroup *entries; - } samr_DispInfoFullGroups; - - typedef struct { - uint32 idx; - lsa_AsciiStringLarge account_name; - } samr_DispEntryAscii; - - typedef struct { - uint32 count; - [size_is(count)] samr_DispEntryAscii *entries; - } samr_DispInfoAscii; - - typedef [switch_type(uint16)] union { - [case(1)] samr_DispInfoGeneral info1;/* users */ - [case(2)] samr_DispInfoFull info2; /* trust accounts? */ - [case(3)] samr_DispInfoFullGroups info3; /* groups */ - [case(4)] samr_DispInfoAscii info4; /* users */ - [case(5)] samr_DispInfoAscii info5; /* groups */ - } samr_DispInfo; - - NTSTATUS samr_QueryDisplayInfo( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [in] uint32 start_idx, - [in] uint32 max_entries, - [in] uint32 buf_size, - [out] uint32 total_size, - [out] uint32 returned_size, - [out,switch_is(level)] samr_DispInfo info - ); - - - /************************/ - /* Function 0x29 */ - - /* - this seems to be an alphabetic search function. The returned index - is the index for samr_QueryDisplayInfo needed to get names occurring - after the specified name. The supplied name does not need to exist - in the database (for example you can supply just a first letter for - searching starting at that letter) - - The level corresponds to the samr_QueryDisplayInfo level - */ - NTSTATUS samr_GetDisplayEnumerationIndex( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [in] lsa_String name, - [out] uint32 idx - ); - - - - /************************/ - /* Function 0x2a */ - - /* - w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this - */ - NTSTATUS samr_TestPrivateFunctionsDomain( - [in,ref] policy_handle *domain_handle - ); - - - /************************/ - /* Function 0x2b */ - - /* - w2k3 returns NT_STATUS_NOT_IMPLEMENTED for this - */ - NTSTATUS samr_TestPrivateFunctionsUser( - [in,ref] policy_handle *user_handle - ); - - - /************************/ - /* Function 0x2c */ - - typedef struct { - uint16 min_password_length; - samr_PasswordProperties password_properties; - } samr_PwInfo; - - [public] NTSTATUS samr_GetUserPwInfo( - [in,ref] policy_handle *user_handle, - [out] samr_PwInfo info - ); - - /************************/ - /* Function 0x2d */ - NTSTATUS samr_RemoveMemberFromForeignDomain( - [in,ref] policy_handle *domain_handle, - [in,ref] dom_sid2 *sid - ); - - /************************/ - /* Function 0x2e */ - - /* - how is this different from QueryDomainInfo ?? - */ - NTSTATUS samr_QueryDomainInfo2( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [out,unique,switch_is(level)] samr_DomainInfo *info - ); - - /************************/ - /* Function 0x2f */ - - /* - how is this different from QueryUserInfo ?? - */ - NTSTATUS samr_QueryUserInfo2( - [in,ref] policy_handle *user_handle, - [in] uint16 level, - [out,unique,switch_is(level)] samr_UserInfo *info - ); - - /************************/ - /* Function 0x30 */ - - /* - how is this different from QueryDisplayInfo?? - */ - NTSTATUS samr_QueryDisplayInfo2( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [in] uint32 start_idx, - [in] uint32 max_entries, - [in] uint32 buf_size, - [out] uint32 total_size, - [out] uint32 returned_size, - [out,switch_is(level)] samr_DispInfo info - ); - - /************************/ - /* Function 0x31 */ - - /* - how is this different from GetDisplayEnumerationIndex ?? - */ - NTSTATUS samr_GetDisplayEnumerationIndex2( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [in] lsa_String name, - [out] uint32 idx - ); - - - /************************/ - /* Function 0x32 */ - NTSTATUS samr_CreateUser2( - [in,ref] policy_handle *domain_handle, - [in,ref] lsa_String *account_name, - [in] samr_AcctFlags acct_flags, - [in] samr_UserAccessMask access_mask, - [out,ref] policy_handle *user_handle, - [out,ref] uint32 *access_granted, - [out,ref] uint32 *rid - ); - - - /************************/ - /* Function 0x33 */ - - /* - another duplicate. There must be a reason .... - */ - NTSTATUS samr_QueryDisplayInfo3( - [in,ref] policy_handle *domain_handle, - [in] uint16 level, - [in] uint32 start_idx, - [in] uint32 max_entries, - [in] uint32 buf_size, - [out] uint32 total_size, - [out] uint32 returned_size, - [out,switch_is(level)] samr_DispInfo info - ); - - /************************/ - /* Function 0x34 */ - NTSTATUS samr_AddMultipleMembersToAlias( - [in,ref] policy_handle *alias_handle, - [in,ref] lsa_SidArray *sids - ); - - /************************/ - /* Function 0x35 */ - NTSTATUS samr_RemoveMultipleMembersFromAlias( - [in,ref] policy_handle *alias_handle, - [in,ref] lsa_SidArray *sids - ); - - /************************/ - /* Function 0x36 */ - - NTSTATUS samr_OemChangePasswordUser2( - [in,unique] lsa_AsciiString *server, - [in,ref] lsa_AsciiString *account, - [in,unique] samr_CryptPassword *password, - [in,unique] samr_Password *hash - ); - - /************************/ - /* Function 0x37 */ - NTSTATUS samr_ChangePasswordUser2( - [in,unique] lsa_String *server, - [in,ref] lsa_String *account, - [in,unique] samr_CryptPassword *nt_password, - [in,unique] samr_Password *nt_verifier, - [in] boolean8 lm_change, - [in,unique] samr_CryptPassword *lm_password, - [in,unique] samr_Password *lm_verifier - ); - - /************************/ - /* Function 0x38 */ - NTSTATUS samr_GetDomPwInfo( - [in,unique] lsa_String *domain_name, - [out] samr_PwInfo info - ); - - /************************/ - /* Function 0x39 */ - NTSTATUS samr_Connect2( - [in,unique,string,charset(UTF16)] uint16 *system_name, - [in] samr_ConnectAccessMask access_mask, - [out,ref] policy_handle *connect_handle - ); - - /************************/ - /* Function 0x3a */ - /* - seems to be an exact alias for samr_SetUserInfo() - */ - [public] NTSTATUS samr_SetUserInfo2( - [in,ref] policy_handle *user_handle, - [in] uint16 level, - [in,ref,switch_is(level)] samr_UserInfo *info - ); - - /************************/ - /* Function 0x3b */ - /* - this one is mysterious. I have a few guesses, but nothing working yet - */ - NTSTATUS samr_SetBootKeyInformation( - [in,ref] policy_handle *connect_handle, - [in] uint32 unknown1, - [in] uint32 unknown2, - [in] uint32 unknown3 - ); - - /************************/ - /* Function 0x3c */ - NTSTATUS samr_GetBootKeyInformation( - [in,ref] policy_handle *domain_handle, - [out] uint32 unknown - ); - - /************************/ - /* Function 0x3d */ - NTSTATUS samr_Connect3( - [in,unique,string,charset(UTF16)] uint16 *system_name, - /* this unknown value seems to be completely ignored by w2k3 */ - [in] uint32 unknown, - [in] samr_ConnectAccessMask access_mask, - [out,ref] policy_handle *connect_handle - ); - - /************************/ - /* Function 0x3e */ - - typedef enum { - SAMR_CONNECT_PRE_W2K = 1, - SAMR_CONNECT_W2K = 2, - SAMR_CONNECT_AFTER_W2K = 3 - } samr_ConnectVersion; - - NTSTATUS samr_Connect4( - [in,unique,string,charset(UTF16)] uint16 *system_name, - [in] samr_ConnectVersion client_version, - [in] samr_ConnectAccessMask access_mask, - [out,ref] policy_handle *connect_handle - ); - - /************************/ - /* Function 0x3f */ - - typedef enum samr_RejectReason samr_RejectReason; - - typedef struct { - samr_RejectReason reason; - uint32 unknown1; - uint32 unknown2; - } samr_ChangeReject; - - NTSTATUS samr_ChangePasswordUser3( - [in,unique] lsa_String *server, - [in,ref] lsa_String *account, - [in,unique] samr_CryptPassword *nt_password, - [in,unique] samr_Password *nt_verifier, - [in] boolean8 lm_change, - [in,unique] samr_CryptPassword *lm_password, - [in,unique] samr_Password *lm_verifier, - [in,unique] samr_CryptPassword *password3, - [out,unique] samr_DomInfo1 *dominfo, - [out,unique] samr_ChangeReject *reject - ); - - /************************/ - /* Function 0x40 */ - - typedef struct { - samr_ConnectVersion client_version; /* w2k3 gives 3 */ - uint32 unknown2; /* w2k3 gives 0 */ - } samr_ConnectInfo1; - - typedef union { - [case(1)] samr_ConnectInfo1 info1; - } samr_ConnectInfo; - - [public] NTSTATUS samr_Connect5( - [in,unique,string,charset(UTF16)] uint16 *system_name, - [in] samr_ConnectAccessMask access_mask, - [in,out] uint32 level, - [in,out,switch_is(level),ref] samr_ConnectInfo *info, - [out,ref] policy_handle *connect_handle - ); - - /************************/ - /* Function 0x41 */ - NTSTATUS samr_RidToSid( - [in,ref] policy_handle *domain_handle, - [in] uint32 rid, - [out,unique] dom_sid2 *sid - ); - - - /************************/ - /* Function 0x42 */ - - /* - this should set the DSRM password for the server, which is used - when booting into Directory Services Recovery Mode on a DC. Win2003 - gives me NT_STATUS_NOT_SUPPORTED - */ - - NTSTATUS samr_SetDsrmPassword( - [in,unique] lsa_String *name, - [in] uint32 unknown, - [in,unique] samr_Password *hash - ); - - - /************************/ - /* Function 0x43 */ - /************************/ - typedef [bitmap32bit] bitmap { - SAMR_VALIDATE_FIELD_PASSWORD_LAST_SET = 0x00000001, - SAMR_VALIDATE_FIELD_BAD_PASSWORD_TIME = 0x00000002, - SAMR_VALIDATE_FIELD_LOCKOUT_TIME = 0x00000004, - SAMR_VALIDATE_FIELD_BAD_PASSWORD_COUNT = 0x00000008, - SAMR_VALIDATE_FIELD_PASSWORD_HISTORY_LENGTH = 0x00000010, - SAMR_VALIDATE_FIELD_PASSWORD_HISTORY = 0x00000020 - } samr_ValidateFieldsPresent; - - typedef enum { - NetValidateAuthentication = 1, - NetValidatePasswordChange= 2, - NetValidatePasswordReset = 3 - } samr_ValidatePasswordLevel; - - /* NetApi maps samr_ValidationStatus errors to WERRORs. Haven't - * identified the mapping of - * - NERR_PasswordFilterError - * - NERR_PasswordExpired and - * - NERR_PasswordCantChange - * yet - Guenther - */ - - typedef enum { - SAMR_VALIDATION_STATUS_SUCCESS = 0, - SAMR_VALIDATION_STATUS_PASSWORD_MUST_CHANGE = 1, - SAMR_VALIDATION_STATUS_ACCOUNT_LOCKED_OUT = 2, - SAMR_VALIDATION_STATUS_BAD_PASSWORD = 4, - SAMR_VALIDATION_STATUS_PWD_HISTORY_CONFLICT = 5, - SAMR_VALIDATION_STATUS_PWD_TOO_SHORT = 6, - SAMR_VALIDATION_STATUS_PWD_TOO_LONG = 7, - SAMR_VALIDATION_STATUS_NOT_COMPLEX_ENOUGH = 8, - SAMR_VALIDATION_STATUS_PASSWORD_TOO_RECENT = 9 - } samr_ValidationStatus; - - typedef struct { - uint32 length; - [size_is(length)] uint8 *data; - } samr_ValidationBlob; - - typedef struct { - samr_ValidateFieldsPresent fields_present; - NTTIME_hyper last_password_change; - NTTIME_hyper bad_password_time; - NTTIME_hyper lockout_time; - uint32 bad_pwd_count; - uint32 pwd_history_len; - [size_is(pwd_history_len)] samr_ValidationBlob *pwd_history; - } samr_ValidatePasswordInfo; - - typedef struct { - samr_ValidatePasswordInfo info; - samr_ValidationStatus status; - } samr_ValidatePasswordRepCtr; - - typedef [switch_type(uint16)] union { - [case(1)] samr_ValidatePasswordRepCtr ctr1; - [case(2)] samr_ValidatePasswordRepCtr ctr2; - [case(3)] samr_ValidatePasswordRepCtr ctr3; - } samr_ValidatePasswordRep; - - typedef struct { - samr_ValidatePasswordInfo info; - lsa_StringLarge password; - lsa_StringLarge account; - samr_ValidationBlob hash; - boolean8 pwd_must_change_at_next_logon; - boolean8 clear_lockout; - } samr_ValidatePasswordReq3; - - typedef struct { - samr_ValidatePasswordInfo info; - lsa_StringLarge password; - lsa_StringLarge account; - samr_ValidationBlob hash; - boolean8 password_matched; - } samr_ValidatePasswordReq2; - - typedef struct { - samr_ValidatePasswordInfo info; - boolean8 password_matched; - } samr_ValidatePasswordReq1; - - typedef [switch_type(uint16)] union { - [case(1)] samr_ValidatePasswordReq1 req1; - [case(2)] samr_ValidatePasswordReq2 req2; - [case(3)] samr_ValidatePasswordReq3 req3; - } samr_ValidatePasswordReq; - - NTSTATUS samr_ValidatePassword( - [in] samr_ValidatePasswordLevel level, - [in,switch_is(level)] samr_ValidatePasswordReq req, - [out,unique,switch_is(level)] samr_ValidatePasswordRep *rep - ); -} diff --git a/source4/librpc/idl/security.idl b/source4/librpc/idl/security.idl deleted file mode 100644 index 40aa698176..0000000000 --- a/source4/librpc/idl/security.idl +++ /dev/null @@ -1,410 +0,0 @@ -#include "idl_types.h" - -/* - security IDL structures -*/ - -import "misc.idl"; - -/* - use the same structure for dom_sid2 as dom_sid. A dom_sid2 is really - just a dom sid, but with the sub_auths represented as a conformant - array. As with all in-structure conformant arrays, the array length - is placed before the start of the structure. That's what gives rise - to the extra num_auths elemenent. We don't want the Samba code to - have to bother with such esoteric NDR details, so its easier to just - define it as a dom_sid and use pidl magic to make it all work. It - just means you need to mark a sid as a "dom_sid2" in the IDL when you - know it is of the conformant array variety -*/ -cpp_quote("#define dom_sid2 dom_sid") - -/* same struct as dom_sid but inside a 28 bytes fixed buffer in NDR */ -cpp_quote("#define dom_sid28 dom_sid") - -/* same struct as dom_sid but in a variable byte buffer, which is maybe empty in NDR */ -cpp_quote("#define dom_sid0 dom_sid") - -[ - pointer_default(unique) -] -interface security -{ - /* - access masks are divided up like this: - 0xabccdddd - where - a = generic rights bits SEC_GENERIC_ - b = flags SEC_FLAG_ - c = standard rights bits SEC_STD_ - d = object type specific bits SEC_{FILE,DIR,REG,xxx}_ - - common combinations of bits are prefixed with SEC_RIGHTS_ - */ - const int SEC_MASK_GENERIC = 0xF0000000; - const int SEC_MASK_FLAGS = 0x0F000000; - const int SEC_MASK_STANDARD = 0x00FF0000; - const int SEC_MASK_SPECIFIC = 0x0000FFFF; - - /* generic bits */ - const int SEC_GENERIC_ALL = 0x10000000; - const int SEC_GENERIC_EXECUTE = 0x20000000; - const int SEC_GENERIC_WRITE = 0x40000000; - const int SEC_GENERIC_READ = 0x80000000; - - /* flag bits */ - const int SEC_FLAG_SYSTEM_SECURITY = 0x01000000; - const int SEC_FLAG_MAXIMUM_ALLOWED = 0x02000000; - - /* standard bits */ - const int SEC_STD_DELETE = 0x00010000; - const int SEC_STD_READ_CONTROL = 0x00020000; - const int SEC_STD_WRITE_DAC = 0x00040000; - const int SEC_STD_WRITE_OWNER = 0x00080000; - const int SEC_STD_SYNCHRONIZE = 0x00100000; - const int SEC_STD_REQUIRED = 0x000F0000; - const int SEC_STD_ALL = 0x001F0000; - - /* file specific bits */ - const int SEC_FILE_READ_DATA = 0x00000001; - const int SEC_FILE_WRITE_DATA = 0x00000002; - const int SEC_FILE_APPEND_DATA = 0x00000004; - const int SEC_FILE_READ_EA = 0x00000008; - const int SEC_FILE_WRITE_EA = 0x00000010; - const int SEC_FILE_EXECUTE = 0x00000020; - const int SEC_FILE_READ_ATTRIBUTE = 0x00000080; - const int SEC_FILE_WRITE_ATTRIBUTE = 0x00000100; - const int SEC_FILE_ALL = 0x000001ff; - - /* directory specific bits */ - const int SEC_DIR_LIST = 0x00000001; - const int SEC_DIR_ADD_FILE = 0x00000002; - const int SEC_DIR_ADD_SUBDIR = 0x00000004; - const int SEC_DIR_READ_EA = 0x00000008; - const int SEC_DIR_WRITE_EA = 0x00000010; - const int SEC_DIR_TRAVERSE = 0x00000020; - const int SEC_DIR_DELETE_CHILD = 0x00000040; - const int SEC_DIR_READ_ATTRIBUTE = 0x00000080; - const int SEC_DIR_WRITE_ATTRIBUTE = 0x00000100; - - /* registry entry specific bits */ - const int SEC_REG_QUERY_VALUE = 0x00000001; - const int SEC_REG_SET_VALUE = 0x00000002; - const int SEC_REG_CREATE_SUBKEY = 0x00000004; - const int SEC_REG_ENUM_SUBKEYS = 0x00000008; - const int SEC_REG_NOTIFY = 0x00000010; - const int SEC_REG_CREATE_LINK = 0x00000020; - - /* ldap specific access bits */ - const int SEC_ADS_CREATE_CHILD = 0x00000001; - const int SEC_ADS_DELETE_CHILD = 0x00000002; - const int SEC_ADS_LIST = 0x00000004; - const int SEC_ADS_SELF_WRITE = 0x00000008; - const int SEC_ADS_READ_PROP = 0x00000010; - const int SEC_ADS_WRITE_PROP = 0x00000020; - const int SEC_ADS_DELETE_TREE = 0x00000040; - const int SEC_ADS_LIST_OBJECT = 0x00000080; - const int SEC_ADS_CONTROL_ACCESS = 0x00000100; - - /* invalid bits */ - const int SEC_MASK_INVALID = 0x0ce0fe00; - - /* generic->specific mappings for files */ - const int SEC_RIGHTS_FILE_READ = SEC_STD_READ_CONTROL | - SEC_STD_SYNCHRONIZE | - SEC_FILE_READ_DATA | - SEC_FILE_READ_ATTRIBUTE | - SEC_FILE_READ_EA; - - const int SEC_RIGHTS_FILE_WRITE = SEC_STD_READ_CONTROL | - SEC_STD_SYNCHRONIZE | - SEC_FILE_WRITE_DATA | - SEC_FILE_WRITE_ATTRIBUTE | - SEC_FILE_WRITE_EA | - SEC_FILE_APPEND_DATA; - - const int SEC_RIGHTS_FILE_EXECUTE = SEC_STD_SYNCHRONIZE | - SEC_STD_READ_CONTROL | - SEC_FILE_READ_ATTRIBUTE | - SEC_FILE_EXECUTE; - - const int SEC_RIGHTS_FILE_ALL = SEC_STD_ALL | SEC_FILE_ALL; - - /* generic->specific mappings for directories (same as files) */ - const int SEC_RIGHTS_DIR_READ = SEC_RIGHTS_FILE_READ; - const int SEC_RIGHTS_DIR_WRITE = SEC_RIGHTS_FILE_WRITE; - const int SEC_RIGHTS_DIR_EXECUTE = SEC_RIGHTS_FILE_EXECUTE; - const int SEC_RIGHTS_DIR_ALL = SEC_RIGHTS_FILE_ALL; - - - /***************************************************************/ - /* WELL KNOWN SIDS */ - - /* a NULL sid */ - const string SID_NULL = "S-1-0-0"; - - /* the world domain */ - const string NAME_WORLD = "WORLD"; - - const string SID_WORLD_DOMAIN = "S-1-1"; - const string SID_WORLD = "S-1-1-0"; - - /* SECURITY_CREATOR_SID_AUTHORITY */ - const string SID_CREATOR_OWNER_DOMAIN = "S-1-3"; - const string SID_CREATOR_OWNER = "S-1-3-0"; - const string SID_CREATOR_GROUP = "S-1-3-1"; - const string SID_OWNER_RIGHTS = "S-1-3-4"; - - /* SECURITY_NT_AUTHORITY */ - const string NAME_NT_AUTHORITY = "NT AUTHORITY"; - - const string SID_NT_AUTHORITY = "S-1-5"; - const string SID_NT_DIALUP = "S-1-5-1"; - const string SID_NT_NETWORK = "S-1-5-2"; - const string SID_NT_BATCH = "S-1-5-3"; - const string SID_NT_INTERACTIVE = "S-1-5-4"; - const string SID_NT_SERVICE = "S-1-5-6"; - const string SID_NT_ANONYMOUS = "S-1-5-7"; - const string SID_NT_PROXY = "S-1-5-8"; - const string SID_NT_ENTERPRISE_DCS = "S-1-5-9"; - const string SID_NT_SELF = "S-1-5-10"; - const string SID_NT_AUTHENTICATED_USERS = "S-1-5-11"; - const string SID_NT_RESTRICTED = "S-1-5-12"; - const string SID_NT_TERMINAL_SERVER_USERS = "S-1-5-13"; - const string SID_NT_REMOTE_INTERACTIVE = "S-1-5-14"; - const string SID_NT_THIS_ORGANISATION = "S-1-5-15"; - const string SID_NT_IUSR = "S-1-5-17"; - const string SID_NT_SYSTEM = "S-1-5-18"; - const string SID_NT_LOCAL_SERVICE = "S-1-5-19"; - const string SID_NT_NETWORK_SERVICE = "S-1-5-20"; - const string SID_NT_DIGEST_AUTHENTICATION = "S-1-5-64-21"; - const string SID_NT_NTLM_AUTHENTICATION = "S-1-5-64-10"; - const string SID_NT_SCHANNEL_AUTHENTICATION = "S-1-5-64-14"; - const string SID_NT_OTHER_ORGANISATION = "S-1-5-1000"; - - /* SECURITY_BUILTIN_DOMAIN_RID */ - const string NAME_BUILTIN = "BUILTIN"; - - const string SID_BUILTIN = "S-1-5-32"; - const string SID_BUILTIN_ADMINISTRATORS = "S-1-5-32-544"; - const string SID_BUILTIN_USERS = "S-1-5-32-545"; - const string SID_BUILTIN_GUESTS = "S-1-5-32-546"; - const string SID_BUILTIN_POWER_USERS = "S-1-5-32-547"; - const string SID_BUILTIN_ACCOUNT_OPERATORS = "S-1-5-32-548"; - const string SID_BUILTIN_SERVER_OPERATORS = "S-1-5-32-549"; - const string SID_BUILTIN_PRINT_OPERATORS = "S-1-5-32-550"; - const string SID_BUILTIN_BACKUP_OPERATORS = "S-1-5-32-551"; - const string SID_BUILTIN_REPLICATOR = "S-1-5-32-552"; - const string SID_BUILTIN_RAS_SERVERS = "S-1-5-32-553"; - const string SID_BUILTIN_PREW2K = "S-1-5-32-554"; - - /* well-known domain RIDs */ - const int DOMAIN_RID_LOGON = 9; - const int DOMAIN_RID_ADMINISTRATOR = 500; - const int DOMAIN_RID_GUEST = 501; - const int DOMAIN_RID_ADMINS = 512; - const int DOMAIN_RID_USERS = 513; - const int DOMAIN_RID_DOMAIN_MEMBERS = 515; - const int DOMAIN_RID_DCS = 516; - const int DOMAIN_RID_CERT_ADMINS = 517; - const int DOMAIN_RID_SCHEMA_ADMINS = 518; - const int DOMAIN_RID_ENTERPRISE_ADMINS = 519; - - - /* - privilege IDs. Please keep the IDs below 64. If we get more - than 64 then we need to change security_token - */ - typedef enum { - SEC_PRIV_SECURITY = 1, - SEC_PRIV_BACKUP = 2, - SEC_PRIV_RESTORE = 3, - SEC_PRIV_SYSTEMTIME = 4, - SEC_PRIV_SHUTDOWN = 5, - SEC_PRIV_REMOTE_SHUTDOWN = 6, - SEC_PRIV_TAKE_OWNERSHIP = 7, - SEC_PRIV_DEBUG = 8, - SEC_PRIV_SYSTEM_ENVIRONMENT = 9, - SEC_PRIV_SYSTEM_PROFILE = 10, - SEC_PRIV_PROFILE_SINGLE_PROCESS = 11, - SEC_PRIV_INCREASE_BASE_PRIORITY = 12, - SEC_PRIV_LOAD_DRIVER = 13, - SEC_PRIV_CREATE_PAGEFILE = 14, - SEC_PRIV_INCREASE_QUOTA = 15, - SEC_PRIV_CHANGE_NOTIFY = 16, - SEC_PRIV_UNDOCK = 17, - SEC_PRIV_MANAGE_VOLUME = 18, - SEC_PRIV_IMPERSONATE = 19, - SEC_PRIV_CREATE_GLOBAL = 20, - SEC_PRIV_ENABLE_DELEGATION = 21, - SEC_PRIV_INTERACTIVE_LOGON = 22, - SEC_PRIV_NETWORK_LOGON = 23, - SEC_PRIV_REMOTE_INTERACTIVE_LOGON = 24 - } sec_privilege; - - - /* a domain SID. Note that unlike Samba3 this contains a pointer, - so you can't copy them using assignment */ - typedef [public,gensize,noprint,noejs,nosize] struct { - uint8 sid_rev_num; /**< SID revision number */ - [range(0,15)] int8 num_auths; /**< Number of sub-authorities */ - uint8 id_auth[6]; /**< Identifier Authority */ - uint32 sub_auths[num_auths]; - } dom_sid; - - /* id used to identify a endpoint, possibly in a cluster */ - typedef [public] struct { - hyper id; - uint32 id2; - uint32 node; - } server_id; - - typedef [bitmap8bit] bitmap { - SEC_ACE_FLAG_OBJECT_INHERIT = 0x01, - SEC_ACE_FLAG_CONTAINER_INHERIT = 0x02, - SEC_ACE_FLAG_NO_PROPAGATE_INHERIT = 0x04, - SEC_ACE_FLAG_INHERIT_ONLY = 0x08, - SEC_ACE_FLAG_INHERITED_ACE = 0x10, - SEC_ACE_FLAG_VALID_INHERIT = 0x0f, - SEC_ACE_FLAG_SUCCESSFUL_ACCESS = 0x40, - SEC_ACE_FLAG_FAILED_ACCESS = 0x80 - } security_ace_flags; - - typedef [enum8bit] enum { - SEC_ACE_TYPE_ACCESS_ALLOWED = 0, - SEC_ACE_TYPE_ACCESS_DENIED = 1, - SEC_ACE_TYPE_SYSTEM_AUDIT = 2, - SEC_ACE_TYPE_SYSTEM_ALARM = 3, - SEC_ACE_TYPE_ALLOWED_COMPOUND = 4, - SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT = 5, - SEC_ACE_TYPE_ACCESS_DENIED_OBJECT = 6, - SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT = 7, - SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT = 8 - } security_ace_type; - - typedef [bitmap32bit] bitmap { - SEC_ACE_OBJECT_TYPE_PRESENT = 0x00000001, - SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT = 0x00000002 - } security_ace_object_flags; - - typedef [nodiscriminant] union { - /* this is the 'schemaIDGUID' attribute of the attribute object in the schema naming context */ - [case(SEC_ACE_OBJECT_TYPE_PRESENT)] GUID type; - [default]; - } security_ace_object_type; - - typedef [nodiscriminant] union { - /* this is the 'schemaIDGUID' attribute of the objectclass object in the schema naming context - * (of the parent container) - */ - [case(SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] GUID inherited_type; - [default]; - } security_ace_object_inherited_type; - - typedef struct { - security_ace_object_flags flags; - [switch_is(flags & SEC_ACE_OBJECT_TYPE_PRESENT)] security_ace_object_type type; - [switch_is(flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT)] security_ace_object_inherited_type inherited_type; - } security_ace_object; - - typedef [nodiscriminant] union { - [case(SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT)] security_ace_object object; - [case(SEC_ACE_TYPE_ACCESS_DENIED_OBJECT)] security_ace_object object; - [case(SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT)] security_ace_object object; - [case(SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT)] security_ace_object object; - [default]; - } security_ace_object_ctr; - - typedef [public,gensize,nosize] struct { - security_ace_type type; /* SEC_ACE_TYPE_* */ - security_ace_flags flags; /* SEC_ACE_FLAG_* */ - [value(ndr_size_security_ace(r,ndr->flags))] uint16 size; - uint32 access_mask; - [switch_is(type)] security_ace_object_ctr object; - dom_sid trustee; - } security_ace; - - typedef enum { - SECURITY_ACL_REVISION_NT4 = 2, - SECURITY_ACL_REVISION_ADS = 4 - } security_acl_revision; - - const uint NT4_ACL_REVISION = SECURITY_ACL_REVISION_NT4; - - typedef [public,gensize,nosize] struct { - security_acl_revision revision; - [value(ndr_size_security_acl(r,ndr->flags))] uint16 size; - [range(0,1000)] uint32 num_aces; - security_ace aces[num_aces]; - } security_acl; - - /* default revision for new ACLs */ - typedef [enum8bit] enum { - SECURITY_DESCRIPTOR_REVISION_1 = 1 - } security_descriptor_revision; - - const int SD_REVISION = SECURITY_DESCRIPTOR_REVISION_1; - - /* security_descriptor->type bits */ - typedef [bitmap16bit] bitmap { - SEC_DESC_OWNER_DEFAULTED = 0x0001, - SEC_DESC_GROUP_DEFAULTED = 0x0002, - SEC_DESC_DACL_PRESENT = 0x0004, - SEC_DESC_DACL_DEFAULTED = 0x0008, - SEC_DESC_SACL_PRESENT = 0x0010, - SEC_DESC_SACL_DEFAULTED = 0x0020, - SEC_DESC_DACL_TRUSTED = 0x0040, - SEC_DESC_SERVER_SECURITY = 0x0080, - SEC_DESC_DACL_AUTO_INHERIT_REQ = 0x0100, - SEC_DESC_SACL_AUTO_INHERIT_REQ = 0x0200, - SEC_DESC_DACL_AUTO_INHERITED = 0x0400, - SEC_DESC_SACL_AUTO_INHERITED = 0x0800, - SEC_DESC_DACL_PROTECTED = 0x1000, - SEC_DESC_SACL_PROTECTED = 0x2000, - SEC_DESC_RM_CONTROL_VALID = 0x4000, - SEC_DESC_SELF_RELATIVE = 0x8000 - } security_descriptor_type; - - typedef [gensize,nosize,public,flag(NDR_LITTLE_ENDIAN)] struct { - security_descriptor_revision revision; - security_descriptor_type type; /* SEC_DESC_xxxx flags */ - [relative] dom_sid *owner_sid; - [relative] dom_sid *group_sid; - [relative] security_acl *sacl; /* system ACL */ - [relative] security_acl *dacl; /* user (discretionary) ACL */ - } security_descriptor; - - typedef [public] struct { - [range(0,0x40000),value(ndr_size_security_descriptor(sd,ndr->flags))] uint32 sd_size; - [subcontext(4)] security_descriptor *sd; - } sec_desc_buf; - - typedef [public] struct { - dom_sid *user_sid; - dom_sid *group_sid; - uint32 num_sids; - [size_is(num_sids)] dom_sid *sids[*]; - udlong privilege_mask; - } security_token; - - /* bits that determine which parts of a security descriptor - are being queried/set */ - typedef [public,bitmap32bit] bitmap { - SECINFO_OWNER = 0x00000001, - SECINFO_GROUP = 0x00000002, - SECINFO_DACL = 0x00000004, - SECINFO_SACL = 0x00000008, - SECINFO_UNPROTECTED_SACL = 0x10000000, - SECINFO_UNPROTECTED_DACL = 0x20000000, - SECINFO_PROTECTED_SACL = 0x40000000, - SECINFO_PROTECTED_DACL = 0x80000000 - } security_secinfo; - - typedef [public,bitmap32bit] bitmap { - KERB_ENCTYPE_DES_CBC_CRC = 0x00000001, - KERB_ENCTYPE_DES_CBC_MD5 = 0x00000002, - KERB_ENCTYPE_RC4_HMAC_MD5 = 0x00000004, - KERB_ENCTYPE_AES128_CTS_HMAC_SHA1_96 = 0x00000008, - KERB_ENCTYPE_AES256_CTS_HMAC_SHA1_96 = 0x00000010 - } kerb_EncTypes; -} diff --git a/source4/librpc/ndr/ndr_sec_helper.c b/source4/librpc/ndr/ndr_dom_sid.c index 1256d7dd2d..b986231b4f 100644 --- a/source4/librpc/ndr/ndr_sec_helper.c +++ b/source4/librpc/ndr/ndr_dom_sid.c @@ -4,6 +4,7 @@ fast routines for getting the wire size of security objects Copyright (C) Andrew Tridgell 2003 + Copyright (C) Stefan Metzmacher 2006-2008 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -54,68 +55,6 @@ size_t ndr_size_dom_sid0(const struct dom_sid *sid, int flags) } /* - return the wire size of a security_ace -*/ -size_t ndr_size_security_ace(const struct security_ace *ace, int flags) -{ - size_t ret; - - if (!ace) return 0; - - ret = 8 + ndr_size_dom_sid(&ace->trustee, flags); - - switch (ace->type) { - case SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT: - case SEC_ACE_TYPE_ACCESS_DENIED_OBJECT: - case SEC_ACE_TYPE_SYSTEM_AUDIT_OBJECT: - case SEC_ACE_TYPE_SYSTEM_ALARM_OBJECT: - ret += 4; /* uint32 bitmap ace->object.object.flags */ - if (ace->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) { - ret += 16; /* GUID ace->object.object.type.type */ - } - if (ace->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) { - ret += 16; /* GUID ace->object.object.inherited_typeinherited_type */ - } - break; - default: - break; - } - - return ret; -} - -/* - return the wire size of a security_acl -*/ -size_t ndr_size_security_acl(const struct security_acl *acl, int flags) -{ - size_t ret; - int i; - if (!acl) return 0; - ret = 8; - for (i=0;i<acl->num_aces;i++) { - ret += ndr_size_security_ace(&acl->aces[i], flags); - } - return ret; -} - -/* - return the wire size of a security descriptor -*/ -size_t ndr_size_security_descriptor(const struct security_descriptor *sd, int flags) -{ - size_t ret; - if (!sd) return 0; - - ret = 20; - ret += ndr_size_dom_sid(sd->owner_sid, flags); - ret += ndr_size_dom_sid(sd->group_sid, flags); - ret += ndr_size_security_acl(sd->dacl, flags); - ret += ndr_size_security_acl(sd->sacl, flags); - return ret; -} - -/* print a dom_sid */ void ndr_print_dom_sid(struct ndr_print *ndr, const char *name, const struct dom_sid *sid) diff --git a/source4/librpc/rpc/dcerpc.c b/source4/librpc/rpc/dcerpc.c index bd8e60d4bd..16ea51e6ff 100644 --- a/source4/librpc/rpc/dcerpc.c +++ b/source4/librpc/rpc/dcerpc.c @@ -31,9 +31,9 @@ #include "auth/gensec/gensec.h" #include "param/param.h" -_PUBLIC_ NTSTATUS dcerpc_init(void) +_PUBLIC_ NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx) { - return gensec_init(global_loadparm); + return gensec_init(lp_ctx); } static void dcerpc_connection_dead(struct dcerpc_connection *conn, NTSTATUS status); @@ -1457,8 +1457,9 @@ _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) ndr_err = call->ndr_pull(pull, NDR_OUT, r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { status = ndr_map_error2ntstatus(ndr_err); - dcerpc_log_packet(table, opnum, NDR_OUT, - &response); + dcerpc_log_packet(p->conn->packet_log_dir, + table, opnum, NDR_OUT, + &response); return status; } @@ -1467,7 +1468,8 @@ _PUBLIC_ NTSTATUS dcerpc_ndr_request_recv(struct rpc_request *req) call->ndr_push, call->ndr_pull, call->ndr_print); if (!NT_STATUS_IS_OK(status)) { - dcerpc_log_packet(table, opnum, NDR_OUT, + dcerpc_log_packet(p->conn->packet_log_dir, + table, opnum, NDR_OUT, &response); return status; } diff --git a/source4/librpc/rpc/dcerpc.h b/source4/librpc/rpc/dcerpc.h index cc8d3d1429..6b9d61dd0f 100644 --- a/source4/librpc/rpc/dcerpc.h +++ b/source4/librpc/rpc/dcerpc.h @@ -40,6 +40,7 @@ enum dcerpc_transport_t { this defines a generic security context for signed/sealed dcerpc pipes. */ struct dcerpc_connection; +struct gensec_settings; struct dcerpc_security { struct dcerpc_auth *auth_info; struct gensec_security *generic_state; @@ -61,6 +62,9 @@ struct dcerpc_connection { struct event_context *event_ctx; struct smb_iconv_convenience *iconv_convenience; + /** Directory in which to save ndrdump-parseable files */ + const char *packet_log_dir; + bool dead; bool free_skipped; @@ -109,10 +113,10 @@ struct dcerpc_pipe { struct dcerpc_connection *conn; struct dcerpc_binding *binding; - /* the last fault code from a DCERPC fault */ + /** the last fault code from a DCERPC fault */ uint32_t last_fault_code; - /* timeout for individual rpc requests, in seconds */ + /** timeout for individual rpc requests, in seconds */ uint32_t request_timeout; }; @@ -305,7 +309,7 @@ NTSTATUS dcerpc_bind_auth_schannel(TALLOC_CTX *tmp_ctx, struct loadparm_context *lp_ctx, uint8_t auth_level); struct event_context *dcerpc_event_context(struct dcerpc_pipe *p); -NTSTATUS dcerpc_init(void); +NTSTATUS dcerpc_init(struct loadparm_context *lp_ctx); struct smbcli_tree *dcerpc_smb_tree(struct dcerpc_connection *c); uint16_t dcerpc_smb_fnum(struct dcerpc_connection *c); NTSTATUS dcerpc_secondary_context(struct dcerpc_pipe *p, @@ -319,7 +323,7 @@ NTSTATUS dcerpc_alter_context(struct dcerpc_pipe *p, NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, const struct ndr_interface_table *table, struct cli_credentials *credentials, - struct loadparm_context *lp_ctx, + struct gensec_settings *gensec_settings, uint8_t auth_type, uint8_t auth_level, const char *service); struct composite_context* dcerpc_pipe_connect_send(TALLOC_CTX *parent_ctx, @@ -345,9 +349,10 @@ NTSTATUS dcerpc_secondary_auth_connection_recv(struct composite_context *c, struct composite_context* dcerpc_secondary_connection_send(struct dcerpc_pipe *p, struct dcerpc_binding *b); -void dcerpc_log_packet(const struct ndr_interface_table *ndr, - uint32_t opnum, uint32_t flags, - DATA_BLOB *pkt); +void dcerpc_log_packet(const char *lockdir, + const struct ndr_interface_table *ndr, + uint32_t opnum, uint32_t flags, + DATA_BLOB *pkt); NTSTATUS dcerpc_binding_build_tower(TALLOC_CTX *mem_ctx, struct dcerpc_binding *binding, struct epm_tower *tower); NTSTATUS dcerpc_floor_get_lhs_data(struct epm_floor *epm_floor, struct ndr_syntax_id *syntax); diff --git a/source4/librpc/rpc/dcerpc_auth.c b/source4/librpc/rpc/dcerpc_auth.c index 2eced55967..14f0f9deb4 100644 --- a/source4/librpc/rpc/dcerpc_auth.c +++ b/source4/librpc/rpc/dcerpc_auth.c @@ -222,7 +222,7 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, struct dcerpc_pipe *p, const struct ndr_interface_table *table, struct cli_credentials *credentials, - struct loadparm_context *lp_ctx, + struct gensec_settings *gensec_settings, uint8_t auth_type, uint8_t auth_level, const char *service) { @@ -251,7 +251,7 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, c->status = gensec_client_start(p, &sec->generic_state, p->conn->event_ctx, - lp_ctx); + gensec_settings); if (!NT_STATUS_IS_OK(c->status)) { DEBUG(1, ("Failed to start GENSEC client mode: %s\n", nt_errstr(c->status))); @@ -291,7 +291,7 @@ struct composite_context *dcerpc_bind_auth_send(TALLOC_CTX *mem_ctx, auth_type, auth_level); if (!NT_STATUS_IS_OK(c->status)) { DEBUG(1, ("Failed to start GENSEC client mechanism %s: %s\n", - gensec_get_name_by_authtype(auth_type), + gensec_get_name_by_authtype(sec->generic_state, auth_type), nt_errstr(c->status))); composite_error(c, c->status); return c; @@ -387,12 +387,12 @@ NTSTATUS dcerpc_bind_auth_recv(struct composite_context *creq) _PUBLIC_ NTSTATUS dcerpc_bind_auth(struct dcerpc_pipe *p, const struct ndr_interface_table *table, struct cli_credentials *credentials, - struct loadparm_context *lp_ctx, + struct gensec_settings *gensec_settings, uint8_t auth_type, uint8_t auth_level, const char *service) { struct composite_context *creq; - creq = dcerpc_bind_auth_send(p, p, table, credentials, lp_ctx, + creq = dcerpc_bind_auth_send(p, p, table, credentials, gensec_settings, auth_type, auth_level, service); return dcerpc_bind_auth_recv(creq); } diff --git a/source4/librpc/rpc/dcerpc_connect.c b/source4/librpc/rpc/dcerpc_connect.c index 9583fcdc02..32485f5653 100644 --- a/source4/librpc/rpc/dcerpc_connect.c +++ b/source4/librpc/rpc/dcerpc_connect.c @@ -116,10 +116,11 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb_send(TALLOC_CT conn->in.called_name = "*SMBSERVER"; /* FIXME: This is invalid */ else conn->in.called_name = s->io.binding->target_hostname; + conn->in.socket_options = lp_socket_options(lp_ctx); conn->in.service = "IPC$"; conn->in.service_type = NULL; conn->in.workgroup = lp_workgroup(lp_ctx); - + conn->in.gensec_settings = lp_gensec_settings(conn, lp_ctx); conn->in.iconv_convenience = lp_iconv_convenience(lp_ctx); lp_smbcli_options(lp_ctx, &conn->in.options); @@ -247,11 +248,16 @@ static struct composite_context *dcerpc_pipe_connect_ncacn_np_smb2_send( lp_smbcli_options(lp_ctx, &options); /* send smb2 connect request */ - conn_req = smb2_connect_send(mem_ctx, s->io.binding->host, "IPC$", + conn_req = smb2_connect_send(mem_ctx, s->io.binding->host, + lp_parm_string_list(mem_ctx, lp_ctx, NULL, "smb2", "ports", NULL), + "IPC$", s->io.resolve_ctx, s->io.creds, c->event_ctx, - &options); + &options, + lp_socket_options(lp_ctx), + lp_gensec_settings(mem_ctx, lp_ctx) + ); composite_continue(c, conn_req, continue_smb2_connect, c); return c; } @@ -740,6 +746,9 @@ _PUBLIC_ struct composite_context* dcerpc_pipe_connect_b_send(TALLOC_CTX *parent s->pipe = dcerpc_pipe_init(c, ev, lp_iconv_convenience(lp_ctx)); if (composite_nomem(s->pipe, c)) return c; + if (DEBUGLEVEL >= 10) + s->pipe->conn->packet_log_dir = lp_lockdir(lp_ctx); + /* store parameters in state structure */ s->binding = binding; s->table = table; diff --git a/source4/librpc/rpc/dcerpc_schannel.c b/source4/librpc/rpc/dcerpc_schannel.c index 13bbc3d51f..e3add82bf2 100644 --- a/source4/librpc/rpc/dcerpc_schannel.c +++ b/source4/librpc/rpc/dcerpc_schannel.c @@ -29,6 +29,7 @@ #include "librpc/gen_ndr/ndr_netlogon_c.h" #include "auth/credentials/credentials.h" #include "librpc/rpc/dcerpc_proto.h" +#include "param/param.h" struct schannel_key_state { struct dcerpc_pipe *pipe; @@ -319,7 +320,7 @@ static void continue_schannel_key(struct composite_context *ctx) /* send bind auth request with received creds */ auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, s->credentials, - s->lp_ctx, + lp_gensec_settings(c, s->lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL, s->auth_level, NULL); if (composite_nomem(auth_req, c)) return; diff --git a/source4/librpc/rpc/dcerpc_secondary.c b/source4/librpc/rpc/dcerpc_secondary.c index b4d5d05b61..8ac235c67c 100644 --- a/source4/librpc/rpc/dcerpc_secondary.c +++ b/source4/librpc/rpc/dcerpc_secondary.c @@ -75,6 +75,9 @@ _PUBLIC_ struct composite_context* dcerpc_secondary_connection_send(struct dcerp s->pipe2 = dcerpc_pipe_init(c, s->pipe->conn->event_ctx, s->pipe->conn->iconv_convenience); if (composite_nomem(s->pipe2, c)) return c; + if (DEBUGLEVEL >= 10) + s->pipe2->conn->packet_log_dir = s->pipe->conn->packet_log_dir; + /* open second dcerpc pipe using the same transport as for primary pipe */ switch (s->pipe->conn->transport.transport) { case NCACN_NP: diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index 32646e85b0..1847b20ee7 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -421,7 +421,8 @@ static void continue_ntlmssp_connection(struct composite_context *ctx) /* initiate a authenticated bind */ auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, + s->credentials, + lp_gensec_settings(c, s->lp_ctx), DCERPC_AUTH_TYPE_NTLMSSP, dcerpc_auth_level(s->pipe->conn), s->table->authservices->names[0]); @@ -453,7 +454,9 @@ static void continue_spnego_after_wrong_pass(struct composite_context *ctx) /* initiate a authenticated bind */ auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO, + s->credentials, + lp_gensec_settings(c, s->lp_ctx), + DCERPC_AUTH_TYPE_SPNEGO, dcerpc_auth_level(s->pipe->conn), s->table->authservices->names[0]); composite_continue(c, auth_req, continue_auth, c); @@ -572,7 +575,9 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, } else { /* try SPNEGO with fallback to NTLMSSP */ auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, DCERPC_AUTH_TYPE_SPNEGO, + s->credentials, + lp_gensec_settings(c, s->lp_ctx), + DCERPC_AUTH_TYPE_SPNEGO, dcerpc_auth_level(conn), s->table->authservices->names[0]); composite_continue(c, auth_req, continue_auth_auto, c); @@ -580,7 +585,9 @@ struct composite_context *dcerpc_pipe_auth_send(struct dcerpc_pipe *p, } auth_req = dcerpc_bind_auth_send(c, s->pipe, s->table, - s->credentials, s->lp_ctx, auth_type, + s->credentials, + lp_gensec_settings(c, s->lp_ctx), + auth_type, dcerpc_auth_level(conn), s->table->authservices->names[0]); composite_continue(c, auth_req, continue_auth, c); @@ -671,19 +678,20 @@ _PUBLIC_ NTSTATUS dcerpc_fetch_session_key(struct dcerpc_pipe *p, this triggers on a debug level of >= 10 */ -_PUBLIC_ void dcerpc_log_packet(const struct ndr_interface_table *ndr, +_PUBLIC_ void dcerpc_log_packet(const char *lockdir, + const struct ndr_interface_table *ndr, uint32_t opnum, uint32_t flags, DATA_BLOB *pkt) { const int num_examples = 20; int i; - if (DEBUGLEVEL < 10) return; + if (lockdir == NULL) return; for (i=0;i<num_examples;i++) { char *name=NULL; asprintf(&name, "%s/rpclog/%s-%u.%d.%s", - lp_lockdir(global_loadparm), ndr->name, opnum, i, + lockdir, ndr->name, opnum, i, (flags&NDR_IN)?"in":"out"); if (name == NULL) { return; diff --git a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c index 1636aa91e7..e67dd01158 100644 --- a/source4/ntptr/simple_ldb/ntptr_simple_ldb.c +++ b/source4/ntptr/simple_ldb/ntptr_simple_ldb.c @@ -125,6 +125,7 @@ static WERROR sptr_OpenPrintServer(struct ntptr_context *ntptr, TALLOC_CTX *mem_ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC_CTX *mem_ctx, struct spoolss_GetPrinterData *r) { + struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, server->ntptr->lp_ctx); if (strcmp("W3SvcInstalled", r->in.value_name) == 0) { r->out.type = SPOOLSS_PRINTER_DATA_TYPE_UINT32; r->out.data.value = 0; @@ -170,9 +171,9 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC enum ndr_err_code ndr_err; struct spoolss_OSVersion os; - os.major = dcesrv_common_get_version_major(mem_ctx, server->ntptr->lp_ctx); - os.minor = dcesrv_common_get_version_minor(mem_ctx, server->ntptr->lp_ctx); - os.build = dcesrv_common_get_version_build(mem_ctx, server->ntptr->lp_ctx); + os.major = server_info->version_major; + os.minor = server_info->version_minor; + os.build = server_info->version_build; os.extra_string = ""; ndr_err = ndr_push_struct_blob(&blob, mem_ctx, lp_iconv_convenience(server->ntptr->lp_ctx), &os, (ndr_push_flags_fn_t)ndr_push_spoolss_OSVersion); @@ -188,9 +189,9 @@ static WERROR sptr_GetPrintServerData(struct ntptr_GenericHandle *server, TALLOC enum ndr_err_code ndr_err; struct spoolss_OSVersionEx os_ex; - os_ex.major = dcesrv_common_get_version_major(mem_ctx, server->ntptr->lp_ctx); - os_ex.minor = dcesrv_common_get_version_minor(mem_ctx, server->ntptr->lp_ctx); - os_ex.build = dcesrv_common_get_version_build(mem_ctx, server->ntptr->lp_ctx); + os_ex.major = server_info->version_major; + os_ex.minor = server_info->version_minor; + os_ex.build = server_info->version_build; os_ex.extra_string = ""; os_ex.unknown2 = 0; os_ex.unknown3 = 0; diff --git a/source4/ntvfs/cifs/vfs_cifs.c b/source4/ntvfs/cifs/vfs_cifs.c index 14bf79ecf6..d133bbc480 100644 --- a/source4/ntvfs/cifs/vfs_cifs.c +++ b/source4/ntvfs/cifs/vfs_cifs.c @@ -199,6 +199,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, /* connect to the server, using the smbd event context */ io.in.dest_host = host; io.in.dest_ports = lp_smb_ports(ntvfs->ctx->lp_ctx); + io.in.socket_options = lp_socket_options(ntvfs->ctx->lp_ctx); io.in.called_name = host; io.in.credentials = credentials; io.in.fallback_to_anonymous = false; @@ -206,6 +207,7 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, io.in.service = remote_share; io.in.service_type = "?????"; io.in.iconv_convenience = lp_iconv_convenience(ntvfs->ctx->lp_ctx); + io.in.gensec_settings = lp_gensec_settings(private, ntvfs->ctx->lp_ctx); lp_smbcli_options(ntvfs->ctx->lp_ctx, &io.in.options); lp_smbcli_session_options(ntvfs->ctx->lp_ctx, &io.in.session_options); diff --git a/source4/ntvfs/smb2/vfs_smb2.c b/source4/ntvfs/smb2/vfs_smb2.c index 2c1461b916..ebb17e2806 100644 --- a/source4/ntvfs/smb2/vfs_smb2.c +++ b/source4/ntvfs/smb2/vfs_smb2.c @@ -226,10 +226,15 @@ static NTSTATUS cvfs_connect(struct ntvfs_module_context *ntvfs, lp_smbcli_options(ntvfs->ctx->lp_ctx, &options); - creq = smb2_connect_send(private, host, remote_share, + creq = smb2_connect_send(private, host, + lp_parm_string_list(private, ntvfs->ctx->lp_ctx, NULL, "smb2", "ports", NULL), + remote_share, lp_resolve_context(ntvfs->ctx->lp_ctx), credentials, - ntvfs->ctx->event_ctx, &options); + ntvfs->ctx->event_ctx, &options, + lp_socket_options(ntvfs->ctx->lp_ctx), + lp_gensec_settings(private, ntvfs->ctx->lp_ctx) + ); status = smb2_connect_recv(creq, private, &tree); NT_STATUS_NOT_OK_RETURN(status); diff --git a/source4/ntvfs/sysdep/inotify.c b/source4/ntvfs/sysdep/inotify.c index 68653d60bd..c47a1216c8 100644 --- a/source4/ntvfs/sysdep/inotify.c +++ b/source4/ntvfs/sysdep/inotify.c @@ -339,10 +339,6 @@ static NTSTATUS inotify_watch(struct sys_notify_context *ctx, /* maybe setup the inotify fd */ if (ctx->private_data == NULL) { NTSTATUS status; - if (!lp_parm_bool(global_loadparm, NULL, "notify", "inotify", true)) { - return NT_STATUS_INVALID_SYSTEM_SERVICE; - } - status = inotify_setup(ctx); NT_STATUS_NOT_OK_RETURN(status); } diff --git a/source4/ntvfs/sysdep/sys_notify.c b/source4/ntvfs/sysdep/sys_notify.c index d84979e44c..a27386bb13 100644 --- a/source4/ntvfs/sysdep/sys_notify.c +++ b/source4/ntvfs/sysdep/sys_notify.c @@ -71,6 +71,17 @@ _PUBLIC_ struct sys_notify_context *sys_notify_context_create(struct share_confi } for (i=0;i<num_backends;i++) { + char *enable_opt_name; + bool enabled; + + enable_opt_name = talloc_asprintf(mem_ctx, "notify:%s", + backends[i].name); + enabled = share_bool_option(scfg, enable_opt_name, true); + talloc_free(enable_opt_name); + + if (!enabled) + continue; + if (strcasecmp(backends[i].name, bname) == 0) { bname = backends[i].name; break; diff --git a/source4/param/loadparm.c b/source4/param/loadparm.c index 18b3dcf75d..d660141efc 100644 --- a/source4/param/loadparm.c +++ b/source4/param/loadparm.c @@ -64,6 +64,9 @@ #include "param/param.h" #include "param/loadparm.h" #include "libcli/raw/libcliraw.h" +#include "rpc_server/common/common.h" +#include "lib/socket/socket.h" +#include "auth/gensec/gensec.h" #define standard_sub_basic talloc_strdup @@ -225,8 +228,6 @@ struct loadparm_service }; -struct loadparm_context *global_loadparm = NULL; - #define NUMPARAMETERS (sizeof(parm_table) / sizeof(struct parm_struct)) @@ -1569,14 +1570,14 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, /* If we already have the option set, override it unless it was a command line option and the new one isn't */ if (strcmp(paramo->key, name) == 0) { - if ((paramo->flags & FLAG_CMDLINE) && + if ((paramo->priority & FLAG_CMDLINE) && !(flags & FLAG_CMDLINE)) { return true; } talloc_free(paramo->value); paramo->value = talloc_strdup(paramo, pszParmValue); - paramo->flags = flags; + paramo->priority = flags; free(name); return true; } @@ -1587,7 +1588,7 @@ static bool lp_do_parameter_parametric(struct loadparm_context *lp_ctx, smb_panic("OOM"); paramo->key = talloc_strdup(paramo, name); paramo->value = talloc_strdup(paramo, pszParmValue); - paramo->flags = flags; + paramo->priority = flags; if (service == NULL) { DLIST_ADD(lp_ctx->globals->param_opt, paramo); } else { @@ -2219,7 +2220,7 @@ static int lp_destructor(struct loadparm_context *lp_ctx) struct param_opt *next; for (data = lp_ctx->globals->param_opt; data; data=next) { next = data->next; - if (data->flags & FLAG_CMDLINE) continue; + if (data->priority & FLAG_CMDLINE) continue; DLIST_REMOVE(lp_ctx->globals->param_opt, data); talloc_free(data); } @@ -2428,7 +2429,10 @@ const char *lp_configfile(struct loadparm_context *lp_ctx) bool lp_load_default(struct loadparm_context *lp_ctx) { - return lp_load(lp_ctx, dyn_CONFIGFILE); + if (getenv("SMB_CONF_PATH")) + return lp_load(lp_ctx, getenv("SMB_CONF_PATH")); + else + return lp_load(lp_ctx, dyn_CONFIGFILE); } /** @@ -2474,6 +2478,16 @@ bool lp_load(struct loadparm_context *lp_ctx, const char *filename) reload_charcnv(lp_ctx); + /* FIXME: ntstatus_check_dos_mapping = lp_nt_status_support(lp_ctx); */ + + /* FIXME: This is a bit of a hack, but we can't use a global, since + * not everything that uses lp also uses the socket library */ + if (lp_parm_bool(lp_ctx, NULL, "socket", "testnonblock", false)) { + setenv("SOCKET_TESTNONBLOCK", "1", 1); + } else { + unsetenv("SOCKET_TESTNONBLOCK"); + } + /* FIXME: Check locale in environment for this: */ if (strcmp(lp_display_charset(lp_ctx), lp_unix_charset(lp_ctx)) != 0) d_set_iconv(smb_iconv_open(lp_display_charset(lp_ctx), lp_unix_charset(lp_ctx))); @@ -2659,3 +2673,26 @@ _PUBLIC_ char *lp_tls_dhpfile(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_c return private_path(mem_ctx, lp_ctx, lp_ctx->globals->tls_dhpfile); } +_PUBLIC_ struct dcerpc_server_info *lp_dcerpc_server_info(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) +{ + struct dcerpc_server_info *ret = talloc_zero(mem_ctx, struct dcerpc_server_info); + + ret->domain_name = talloc_reference(mem_ctx, lp_workgroup(lp_ctx)); + ret->version_major = lp_parm_int(lp_ctx, NULL, "server_info", "version_major", 5); + ret->version_minor = lp_parm_int(lp_ctx, NULL, "server_info", "version_minor", 2); + ret->version_build = lp_parm_int(lp_ctx, NULL, "server_info", "version_build", 3790); + + return ret; +} + +struct gensec_settings *lp_gensec_settings(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) +{ + struct gensec_settings *settings = talloc(mem_ctx, struct gensec_settings); + if (settings == NULL) + return NULL; + SMB_ASSERT(lp_ctx != NULL); + settings->lp_ctx = talloc_reference(settings, lp_ctx); + settings->iconv_convenience = lp_iconv_convenience(lp_ctx); + settings->target_hostname = lp_parm_string(lp_ctx, NULL, "gensec", "target_hostname"); + return settings; +} diff --git a/source4/param/param.h b/source4/param/param.h index 85db1c3857..ba0dbfd0fa 100644 --- a/source4/param/param.h +++ b/source4/param/param.h @@ -24,7 +24,7 @@ struct param_opt { struct param_opt *prev, *next; char *key; char *value; - int flags; + int priority; }; struct param_context { @@ -67,11 +67,10 @@ struct loadparm_context; struct loadparm_service; struct smbcli_options; struct smbcli_session_options; +struct gensec_settings; void reload_charcnv(struct loadparm_context *lp_ctx); -extern _DEPRECATED_ struct loadparm_context *global_loadparm; - struct loadparm_service *lp_default_service(struct loadparm_context *lp_ctx); struct parm_struct *lp_parm_table(void); int lp_server_role(struct loadparm_context *); @@ -166,7 +165,6 @@ int lp_cli_minprotocol(struct loadparm_context *); int lp_security(struct loadparm_context *); bool lp_paranoid_server_security(struct loadparm_context *); int lp_announce_as(struct loadparm_context *); -const char **lp_js_include(struct loadparm_context *); const char *lp_servicename(const struct loadparm_service *service); const char *lp_pathname(struct loadparm_service *, struct loadparm_service *); @@ -196,6 +194,7 @@ int lp_server_signing(struct loadparm_context *); int lp_client_signing(struct loadparm_context *); const char *lp_ntp_signd_socket_directory(struct loadparm_context *); + const char *lp_get_parametric(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *type, const char *option); @@ -327,6 +326,9 @@ void lp_smbcli_options(struct loadparm_context *lp_ctx, struct smbcli_options *options); void lp_smbcli_session_options(struct loadparm_context *lp_ctx, struct smbcli_session_options *options); +struct dcerpc_server_info *lp_dcerpc_server_info(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); +struct gensec_settings *lp_gensec_settings(TALLOC_CTX *, struct loadparm_context *); + /* The following definitions come from param/generic.c */ diff --git a/source4/param/param.i b/source4/param/param.i index 6158c92f80..c085ca2f05 100644 --- a/source4/param/param.i +++ b/source4/param/param.i @@ -344,4 +344,13 @@ struct loadparm_context *lp_from_py_object(PyObject *py_obj) return lp_ctx; } +struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx) +{ + struct loadparm_context *ret; + ret = loadparm_init(mem_ctx); + if (!lp_load_default(ret)) + return NULL; + return ret; +} + %} diff --git a/source4/param/param_wrap.c b/source4/param/param_wrap.c index 23b3c17623..8f4f529532 100644 --- a/source4/param/param_wrap.c +++ b/source4/param/param_wrap.c @@ -2814,6 +2814,15 @@ struct loadparm_context *lp_from_py_object(PyObject *py_obj) return lp_ctx; } +struct loadparm_context *py_default_loadparm_context(TALLOC_CTX *mem_ctx) +{ + struct loadparm_context *ret; + ret = loadparm_init(mem_ctx); + if (!lp_load_default(ret)) + return NULL; + return ret; +} + #ifdef __cplusplus extern "C" { diff --git a/source4/rpc_server/common/common.h b/source4/rpc_server/common/common.h index af2d96cb3e..aacd460388 100644 --- a/source4/rpc_server/common/common.h +++ b/source4/rpc_server/common/common.h @@ -20,18 +20,26 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ +#ifndef _DCERPC_SERVER_COMMON_H_ +#define _DCERPC_SERVER_COMMON_H_ + struct share_config; struct dcesrv_context; enum srvsvc_ShareType dcesrv_common_get_share_type(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg); enum srvsvc_PlatformId dcesrv_common_get_platform_id(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx); -const char *dcesrv_common_get_domain_name(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx); const char *dcesrv_common_get_lan_root(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx); const char *dcesrv_common_get_server_name(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, const char *server_unc); -uint32_t dcesrv_common_get_version_major(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); -uint32_t dcesrv_common_get_version_minor(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); -uint32_t dcesrv_common_get_version_build(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx); uint32_t dcesrv_common_get_share_permissions(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg); uint32_t dcesrv_common_get_share_current_users(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg); const char *dcesrv_common_get_share_path(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx, struct share_config *scfg); struct dcesrv_context; + +struct dcerpc_server_info { + const char *domain_name; + uint32_t version_major; + uint32_t version_minor; + uint32_t version_build; +}; + +#endif /* _DCERPC_SERVER_COMMON_H_ */ diff --git a/source4/rpc_server/common/server_info.c b/source4/rpc_server/common/server_info.c index ab04b3af1f..59cdd642bb 100644 --- a/source4/rpc_server/common/server_info.c +++ b/source4/rpc_server/common/server_info.c @@ -60,28 +60,6 @@ const char *dcesrv_common_get_server_name(TALLOC_CTX *mem_ctx, struct dcesrv_con return talloc_strdup(mem_ctx, p); } -const char *dcesrv_common_get_domain_name(TALLOC_CTX *mem_ctx, struct dcesrv_context *dce_ctx) -{ - return talloc_strdup(mem_ctx, lp_workgroup(dce_ctx->lp_ctx)); -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_version_major(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) -{ - return lp_parm_int(lp_ctx, NULL, "server_info", "version_major", 5); -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_version_minor(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) -{ - return lp_parm_int(lp_ctx, NULL, "server_info", "version_minor", 2); -} - -/* This hardcoded value should go into a ldb database! */ -uint32_t dcesrv_common_get_version_build(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) -{ - return lp_parm_int(lp_ctx, NULL, "server_info", "version_build", 3790); -} /* This hardcoded value should go into a ldb database! */ uint32_t dcesrv_common_get_server_type(TALLOC_CTX *mem_ctx, struct event_context *event_ctx, struct dcesrv_context *dce_ctx) diff --git a/source4/rpc_server/dcerpc_server.c b/source4/rpc_server/dcerpc_server.c index 1d1efa7480..6f3f6799e7 100644 --- a/source4/rpc_server/dcerpc_server.c +++ b/source4/rpc_server/dcerpc_server.c @@ -339,6 +339,7 @@ _PUBLIC_ NTSTATUS dcesrv_endpoint_connect(struct dcesrv_context *dce_ctx, p->endpoint = ep; p->contexts = NULL; p->call_list = NULL; + p->packet_log_dir = lp_lockdir(dce_ctx->lp_ctx); p->incoming_fragmented_call_list = NULL; p->pending_call_list = NULL; p->cli_max_recv_frag = 0; diff --git a/source4/rpc_server/dcerpc_server.h b/source4/rpc_server/dcerpc_server.h index 59a4bab083..4788fb3a51 100644 --- a/source4/rpc_server/dcerpc_server.h +++ b/source4/rpc_server/dcerpc_server.h @@ -210,6 +210,8 @@ struct dcesrv_connection { bool processing; + const char *packet_log_dir; + /* this is the default state_flags for dcesrv_call_state structs */ uint32_t state_flags; diff --git a/source4/rpc_server/dcesrv_auth.c b/source4/rpc_server/dcesrv_auth.c index bef7e4be78..5169031d16 100644 --- a/source4/rpc_server/dcesrv_auth.c +++ b/source4/rpc_server/dcesrv_auth.c @@ -61,7 +61,9 @@ bool dcesrv_auth_bind(struct dcesrv_call_state *call) return false; } - status = gensec_server_start(dce_conn, call->event_ctx, call->conn->dce_ctx->lp_ctx, call->msg_ctx, &auth->gensec_security); + status = gensec_server_start(dce_conn, call->event_ctx, + lp_gensec_settings(dce_conn, call->conn->dce_ctx->lp_ctx), + call->msg_ctx, &auth->gensec_security); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC for DCERPC server: %s\n", nt_errstr(status))); return false; diff --git a/source4/rpc_server/remote/dcesrv_remote.c b/source4/rpc_server/remote/dcesrv_remote.c index 3cf8fbe8fb..1310ecee90 100644 --- a/source4/rpc_server/remote/dcesrv_remote.c +++ b/source4/rpc_server/remote/dcesrv_remote.c @@ -144,7 +144,8 @@ static NTSTATUS remote_op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_CT /* unravel the NDR for the packet */ ndr_err = table->calls[opnum].ndr_pull(pull, NDR_IN, *r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - dcerpc_log_packet(table, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + table, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); dce_call->fault_code = DCERPC_FAULT_NDR; return NT_STATUS_NET_WRITE_FAULT; diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index 22d201e58e..c093b536da 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -37,26 +37,28 @@ #include "../lib/util/util_ldb.h" #include "param/param.h" -/* these query macros make samr_Query[User|Group]Info a bit easier to read */ +/* these query macros make samr_Query[User|Group|Alias]Info a bit easier to read */ #define QUERY_STRING(msg, field, attr) \ - r->out.info->field.string = samdb_result_string(msg, attr, ""); + info->field.string = samdb_result_string(msg, attr, ""); #define QUERY_UINT(msg, field, attr) \ - r->out.info->field = samdb_result_uint(msg, attr, 0); + info->field = samdb_result_uint(msg, attr, 0); #define QUERY_RID(msg, field, attr) \ - r->out.info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0); + info->field = samdb_result_rid_from_sid(mem_ctx, msg, attr, 0); #define QUERY_UINT64(msg, field, attr) \ - r->out.info->field = samdb_result_uint64(msg, attr, 0); + info->field = samdb_result_uint64(msg, attr, 0); #define QUERY_APASSC(msg, field, attr) \ - r->out.info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \ - a_state->domain_state->domain_dn, msg, attr); + info->field = samdb_result_allow_password_change(sam_ctx, mem_ctx, \ + a_state->domain_state->domain_dn, msg, attr); #define QUERY_FPASSC(msg, field, attr) \ - r->out.info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \ - a_state->domain_state->domain_dn, msg); + info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \ + a_state->domain_state->domain_dn, msg); #define QUERY_LHOURS(msg, field, attr) \ - r->out.info->field = samdb_result_logon_hours(mem_ctx, msg, attr); + info->field = samdb_result_logon_hours(mem_ctx, msg, attr); #define QUERY_AFLAGS(msg, field, attr) \ - r->out.info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn); + info->field = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, a_state->domain_state->domain_dn); +#define QUERY_PARAMETERS(msg, field, attr) \ + info->field = samdb_result_parameters(mem_ctx, msg, attr); /* these are used to make the Set[User|Group]Info code easier to follow */ @@ -136,6 +138,16 @@ set_el->flags = LDB_FLAG_MOD_REPLACE; \ } while (0) +#define SET_PARAMETERS(msg, field, attr) do { \ + struct ldb_message_element *set_el; \ + if (samdb_msg_add_parameters(sam_ctx, mem_ctx, msg, attr, &r->in.info->field) != 0) { \ + return NT_STATUS_NO_MEMORY; \ + } \ + set_el = ldb_msg_find_element(msg, attr); \ + set_el->flags = LDB_FLAG_MOD_REPLACE; \ +} while (0) + + /* samr_Connect @@ -217,7 +229,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA struct dcesrv_handle *h; struct sec_desc_buf *sd; - r->out.sdbuf = NULL; + *r->out.sdbuf = NULL; DCESRV_PULL_HANDLE(h, r->in.handle, DCESRV_HANDLE_ANY); @@ -228,7 +240,7 @@ static NTSTATUS dcesrv_samr_QuerySecurity(struct dcesrv_call_state *dce_call, TA sd->sd = samdb_default_security_descriptor(mem_ctx); - r->out.sdbuf = sd; + *r->out.sdbuf = sd; return NT_STATUS_OK; } @@ -265,7 +277,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL int ret; struct ldb_dn *partitions_basedn; - r->out.sid = NULL; + *r->out.sid = NULL; DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT); @@ -307,7 +319,7 @@ static NTSTATUS dcesrv_samr_LookupDomain(struct dcesrv_call_state *dce_call, TAL return NT_STATUS_NO_SUCH_DOMAIN; } - r->out.sid = sid; + *r->out.sid = sid; return NT_STATUS_OK; } @@ -332,8 +344,8 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL struct ldb_dn *partitions_basedn; *r->out.resume_handle = 0; - r->out.sam = NULL; - r->out.num_entries = 0; + *r->out.sam = NULL; + *r->out.num_entries = 0; DCESRV_PULL_HANDLE(h, r->in.connect_handle, SAMR_HANDLE_CONNECT); @@ -389,9 +401,9 @@ static NTSTATUS dcesrv_samr_EnumDomains(struct dcesrv_call_state *dce_call, TALL } } - r->out.sam = array; - r->out.num_entries = i; - array->count = r->out.num_entries; + *r->out.sam = array; + *r->out.num_entries = i; + array->count = *r->out.num_entries; return NT_STATUS_OK; } @@ -765,18 +777,19 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, { struct dcesrv_handle *h; struct samr_domain_state *d_state; + union samr_DomainInfo *info; struct ldb_message **dom_msgs; const char * const *attrs = NULL; - r->out.info = NULL; + *r->out.info = NULL; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); d_state = h->data; - r->out.info = talloc(mem_ctx, union samr_DomainInfo); - if (!r->out.info) { + info = talloc(mem_ctx, union samr_DomainInfo); + if (!info) { return NT_STATUS_NO_MEMORY; } @@ -881,47 +894,49 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo(struct dcesrv_call_state *dce_call, } } - ZERO_STRUCTP(r->out.info); + *r->out.info = info; + + ZERO_STRUCTP(info); switch (r->in.level) { case 1: return dcesrv_samr_info_DomInfo1(d_state, mem_ctx, dom_msgs, - &r->out.info->info1); + &info->info1); case 2: return dcesrv_samr_info_DomGeneralInformation(d_state, mem_ctx, dom_msgs, - &r->out.info->general); + &info->general); case 3: return dcesrv_samr_info_DomInfo3(d_state, mem_ctx, dom_msgs, - &r->out.info->info3); + &info->info3); case 4: return dcesrv_samr_info_DomOEMInformation(d_state, mem_ctx, dom_msgs, - &r->out.info->oem); + &info->oem); case 5: return dcesrv_samr_info_DomInfo5(d_state, mem_ctx, dom_msgs, - &r->out.info->info5); + &info->info5); case 6: return dcesrv_samr_info_DomInfo6(d_state, mem_ctx, dom_msgs, - &r->out.info->info6); + &info->info6); case 7: return dcesrv_samr_info_DomInfo7(d_state, mem_ctx, dom_msgs, - &r->out.info->info7); + &info->info7); case 8: return dcesrv_samr_info_DomInfo8(d_state, mem_ctx, dom_msgs, - &r->out.info->info8); + &info->info8); case 9: return dcesrv_samr_info_DomInfo9(d_state, mem_ctx, dom_msgs, - &r->out.info->info9); + &info->info9); case 11: return dcesrv_samr_info_DomGeneralInformation2(d_state, mem_ctx, dom_msgs, - &r->out.info->general2); + &info->general2); case 12: return dcesrv_samr_info_DomInfo12(d_state, mem_ctx, dom_msgs, - &r->out.info->info12); + &info->info12); case 13: return dcesrv_samr_info_DomInfo13(d_state, mem_ctx, dom_msgs, - &r->out.info->info13); + &info->info13); } - + return NT_STATUS_INVALID_INFO_CLASS; } @@ -1135,10 +1150,11 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, int ldb_cnt, count, i, first; struct samr_SamEntry *entries; const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL }; + struct samr_SamArray *sam; *r->out.resume_handle = 0; - r->out.sam = NULL; - r->out.num_entries = 0; + *r->out.sam = NULL; + *r->out.num_entries = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); @@ -1189,20 +1205,22 @@ static NTSTATUS dcesrv_samr_EnumDomainGroups(struct dcesrv_call_state *dce_call, /* return the rest, limit by max_size. Note that we use the w2k3 element size value of 54 */ - r->out.num_entries = count - first; - r->out.num_entries = MIN(r->out.num_entries, + *r->out.num_entries = count - first; + *r->out.num_entries = MIN(*r->out.num_entries, 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER)); - r->out.sam = talloc(mem_ctx, struct samr_SamArray); - if (!r->out.sam) { + sam = talloc(mem_ctx, struct samr_SamArray); + if (!sam) { return NT_STATUS_NO_MEMORY; } - r->out.sam->entries = entries+first; - r->out.sam->count = r->out.num_entries; + sam->entries = entries+first; + sam->count = *r->out.num_entries; - if (r->out.num_entries < count - first) { - *r->out.resume_handle = entries[first+r->out.num_entries-1].idx; + *r->out.sam = sam; + + if (*r->out.num_entries < count - first) { + *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx; return STATUS_MORE_ENTRIES; } @@ -1492,10 +1510,11 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call, int ret, num_filtered_entries, i, first; struct samr_SamEntry *entries; const char * const attrs[] = { "objectSid", "sAMAccountName", "userAccountControl", NULL }; + struct samr_SamArray *sam; *r->out.resume_handle = 0; - r->out.sam = NULL; - r->out.num_entries = 0; + *r->out.sam = NULL; + *r->out.num_entries = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); @@ -1539,24 +1558,26 @@ static NTSTATUS dcesrv_samr_EnumDomainUsers(struct dcesrv_call_state *dce_call, /* return the rest, limit by max_size. Note that we use the w2k3 element size value of 54 */ - r->out.num_entries = num_filtered_entries - first; - r->out.num_entries = MIN(r->out.num_entries, + *r->out.num_entries = num_filtered_entries - first; + *r->out.num_entries = MIN(*r->out.num_entries, 1+(r->in.max_size/SAMR_ENUM_USERS_MULTIPLIER)); - r->out.sam = talloc(mem_ctx, struct samr_SamArray); - if (!r->out.sam) { + sam = talloc(mem_ctx, struct samr_SamArray); + if (!sam) { return NT_STATUS_NO_MEMORY; } - r->out.sam->entries = entries+first; - r->out.sam->count = r->out.num_entries; + sam->entries = entries+first; + sam->count = *r->out.num_entries; + + *r->out.sam = sam; if (first == num_filtered_entries) { return NT_STATUS_OK; } - if (r->out.num_entries < num_filtered_entries - first) { - *r->out.resume_handle = entries[first+r->out.num_entries-1].idx; + if (*r->out.num_entries < num_filtered_entries - first) { + *r->out.resume_handle = entries[first+*r->out.num_entries-1].idx; return STATUS_MORE_ENTRIES; } @@ -1685,10 +1706,11 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call int ldb_cnt, count, i, first; struct samr_SamEntry *entries; const char * const attrs[3] = { "objectSid", "sAMAccountName", NULL }; + struct samr_SamArray *sam; *r->out.resume_handle = 0; - r->out.sam = NULL; - r->out.num_entries = 0; + *r->out.sam = NULL; + *r->out.num_entries = 0; DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); @@ -1748,20 +1770,22 @@ static NTSTATUS dcesrv_samr_EnumDomainAliases(struct dcesrv_call_state *dce_call return NT_STATUS_OK; } - r->out.num_entries = count - first; - r->out.num_entries = MIN(r->out.num_entries, 1000); + *r->out.num_entries = count - first; + *r->out.num_entries = MIN(*r->out.num_entries, 1000); - r->out.sam = talloc(mem_ctx, struct samr_SamArray); - if (!r->out.sam) { + sam = talloc(mem_ctx, struct samr_SamArray); + if (!sam) { return NT_STATUS_NO_MEMORY; } - r->out.sam->entries = entries+first; - r->out.sam->count = r->out.num_entries; + sam->entries = entries+first; + sam->count = *r->out.num_entries; + + *r->out.sam = sam; - if (r->out.num_entries < count - first) { + if (*r->out.num_entries < count - first) { *r->out.resume_handle = - entries[first+r->out.num_entries-1].idx; + entries[first+*r->out.num_entries-1].idx; return STATUS_MORE_ENTRIES; } @@ -1859,8 +1883,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL const char * const attrs[] = { "sAMAccountType", "objectSid", NULL }; int count; - ZERO_STRUCT(r->out.rids); - ZERO_STRUCT(r->out.types); + ZERO_STRUCTP(r->out.rids); + ZERO_STRUCTP(r->out.types); DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); @@ -1870,13 +1894,13 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL return NT_STATUS_OK; } - r->out.rids.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names); - r->out.types.ids = talloc_array(mem_ctx, uint32_t, r->in.num_names); - if (!r->out.rids.ids || !r->out.types.ids) { + r->out.rids->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names); + r->out.types->ids = talloc_array(mem_ctx, uint32_t, r->in.num_names); + if (!r->out.rids->ids || !r->out.types->ids) { return NT_STATUS_NO_MEMORY; } - r->out.rids.count = r->in.num_names; - r->out.types.count = r->in.num_names; + r->out.rids->count = r->in.num_names; + r->out.types->count = r->in.num_names; num_mapped = 0; @@ -1885,8 +1909,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL struct dom_sid *sid; uint32_t atype, rtype; - r->out.rids.ids[i] = 0; - r->out.types.ids[i] = SID_NAME_UNKNOWN; + r->out.rids->ids[i] = 0; + r->out.types->ids[i] = SID_NAME_UNKNOWN; count = gendb_search(d_state->sam_ctx, mem_ctx, d_state->domain_dn, &res, attrs, "sAMAccountName=%s", @@ -1915,8 +1939,8 @@ static NTSTATUS dcesrv_samr_LookupNames(struct dcesrv_call_state *dce_call, TALL continue; } - r->out.rids.ids[i] = sid->sub_auths[sid->num_auths-1]; - r->out.types.ids[i] = rtype; + r->out.rids->ids[i] = sid->sub_auths[sid->num_auths-1]; + r->out.types->ids[i] = rtype; num_mapped++; } @@ -1940,8 +1964,8 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO struct lsa_String *names; uint32_t *ids; - ZERO_STRUCT(r->out.names); - ZERO_STRUCT(r->out.types); + ZERO_STRUCTP(r->out.names); + ZERO_STRUCTP(r->out.types); DCESRV_PULL_HANDLE(h, r->in.domain_handle, SAMR_HANDLE_DOMAIN); @@ -2002,11 +2026,11 @@ static NTSTATUS dcesrv_samr_LookupRids(struct dcesrv_call_state *dce_call, TALLO } } - r->out.names.names = names; - r->out.names.count = r->in.num_rids; + r->out.names->names = names; + r->out.names->count = r->in.num_rids; - r->out.types.ids = ids; - r->out.types.count = r->in.num_rids; + r->out.types->ids = ids; + r->out.types->count = r->in.num_rids; return status; } @@ -2103,8 +2127,9 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T const char * const attrs[4] = { "sAMAccountName", "description", "numMembers", NULL }; int ret; + union samr_GroupInfo *info; - r->out.info = NULL; + *r->out.info = NULL; DCESRV_PULL_HANDLE(h, r->in.group_handle, SAMR_HANDLE_GROUP); @@ -2127,17 +2152,16 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T msg = res->msgs[0]; /* allocate the info structure */ - r->out.info = talloc(mem_ctx, union samr_GroupInfo); - if (r->out.info == NULL) { + info = talloc_zero(mem_ctx, union samr_GroupInfo); + if (info == NULL) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(r->out.info); /* Fill in the level */ switch (r->in.level) { case GROUPINFOALL: QUERY_STRING(msg, all.name, "sAMAccountName"); - r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ + info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ QUERY_UINT (msg, all.num_members, "numMembers") QUERY_STRING(msg, all.description, "description"); break; @@ -2145,22 +2169,24 @@ static NTSTATUS dcesrv_samr_QueryGroupInfo(struct dcesrv_call_state *dce_call, T QUERY_STRING(msg, name, "sAMAccountName"); break; case GROUPINFOATTRIBUTES: - r->out.info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ + info->attributes.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ break; case GROUPINFODESCRIPTION: QUERY_STRING(msg, description, "description"); break; case GROUPINFOALL2: QUERY_STRING(msg, all2.name, "sAMAccountName"); - r->out.info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ + info->all.attributes = SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED; /* Do like w2k3 */ QUERY_UINT (msg, all2.num_members, "numMembers") QUERY_STRING(msg, all2.description, "description"); break; default: - r->out.info = NULL; + talloc_free(info); return NT_STATUS_INVALID_INFO_CLASS; } - + + *r->out.info = info; + return NT_STATUS_OK; } @@ -2451,7 +2477,7 @@ static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call, struct ldb_message **res2; const char * const attrs2[2] = { "objectSid", NULL }; ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, - ldb_dn_new(mem_ctx, a_state->sam_ctx, (const char *)el->values[i].data), + ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]), &res2, attrs2); if (ret != 1) return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -2467,7 +2493,7 @@ static NTSTATUS dcesrv_samr_QueryGroupMember(struct dcesrv_call_state *dce_call, } } - r->out.rids = array; + *r->out.rids = array; return NT_STATUS_OK; } @@ -2574,8 +2600,9 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T const char * const attrs[4] = { "sAMAccountName", "description", "numMembers", NULL }; int ret; + union samr_AliasInfo *info; - r->out.info = NULL; + *r->out.info = NULL; DCESRV_PULL_HANDLE(h, r->in.alias_handle, SAMR_HANDLE_ALIAS); @@ -2590,11 +2617,10 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T msg = res[0]; /* allocate the info structure */ - r->out.info = talloc(mem_ctx, union samr_AliasInfo); - if (r->out.info == NULL) { + info = talloc_zero(mem_ctx, union samr_AliasInfo); + if (info == NULL) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(r->out.info); switch(r->in.level) { case ALIASINFOALL: @@ -2609,10 +2635,12 @@ static NTSTATUS dcesrv_samr_QueryAliasInfo(struct dcesrv_call_state *dce_call, T QUERY_STRING(msg, description, "description"); break; default: - r->out.info = NULL; + talloc_free(info); return NT_STATUS_INVALID_INFO_CLASS; } - + + *r->out.info = info; + return NT_STATUS_OK; } @@ -2824,8 +2852,13 @@ static NTSTATUS dcesrv_samr_GetMembersInAlias(struct dcesrv_call_state *dce_call ret = gendb_search_dn(d_state->sam_ctx, mem_ctx, a_state->account_dn, &msgs, attrs); - if (ret != 1) + if (ret == -1) { + return NT_STATUS_INTERNAL_DB_CORRUPTION; + } else if (ret == 0) { + return NT_STATUS_OBJECT_NAME_NOT_FOUND; + } else if (ret != 1) { return NT_STATUS_INTERNAL_DB_CORRUPTION; + } r->out.sids->num_sids = 0; r->out.sids->sids = NULL; @@ -2845,8 +2878,8 @@ static NTSTATUS dcesrv_samr_GetMembersInAlias(struct dcesrv_call_state *dce_call struct ldb_message **msgs2; const char * const attrs2[2] = { "objectSid", NULL }; ret = gendb_search_dn(a_state->sam_ctx, mem_ctx, - ldb_dn_new(mem_ctx, a_state->sam_ctx, (const char *)el->values[i].data), - &msgs2, attrs2); + ldb_dn_from_ldb_val(mem_ctx, a_state->sam_ctx, &el->values[i]), + &msgs2, attrs2); if (ret != 1) return NT_STATUS_INTERNAL_DB_CORRUPTION; @@ -2984,8 +3017,9 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA struct ldb_context *sam_ctx; const char * const *attrs = NULL; + union samr_UserInfo *info; - r->out.info = NULL; + *r->out.info = NULL; DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER); @@ -3170,11 +3204,10 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA msg = res[0]; /* allocate the info structure */ - r->out.info = talloc(mem_ctx, union samr_UserInfo); - if (r->out.info == NULL) { + info = talloc_zero(mem_ctx, union samr_UserInfo); + if (info == NULL) { return NT_STATUS_NO_MEMORY; } - ZERO_STRUCTP(r->out.info); /* fill in the reply */ switch (r->in.level) { @@ -3285,7 +3318,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA break; case 20: - QUERY_STRING(msg, info20.parameters, "userParameters"); + QUERY_PARAMETERS(msg, info20.parameters, "userParameters"); break; case 21: @@ -3304,11 +3337,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA QUERY_STRING(msg, info21.description, "description"); QUERY_STRING(msg, info21.workstations, "userWorkstations"); QUERY_STRING(msg, info21.comment, "comment"); - QUERY_STRING(msg, info21.parameters, "userParameters"); + QUERY_PARAMETERS(msg, info21.parameters, "userParameters"); QUERY_RID (msg, info21.rid, "objectSid"); QUERY_UINT (msg, info21.primary_gid, "primaryGroupID"); QUERY_AFLAGS(msg, info21.acct_flags, "userAccountControl"); - r->out.info->info21.fields_present = 0x00FFFFFF; + info->info21.fields_present = 0x00FFFFFF; QUERY_LHOURS(msg, info21.logon_hours, "logonHours"); QUERY_UINT (msg, info21.bad_password_count, "badPwdCount"); QUERY_UINT (msg, info21.logon_count, "logonCount"); @@ -3318,10 +3351,12 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA default: - r->out.info = NULL; + talloc_free(info); return NT_STATUS_INVALID_INFO_CLASS; } - + + *r->out.info = info; + return NT_STATUS_OK; } @@ -3411,7 +3446,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL break; case 20: - SET_STRING(msg, info20.parameters, "userParameters"); + SET_PARAMETERS(msg, info20.parameters, "userParameters"); break; case 21: @@ -3441,7 +3476,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL IFSET(SAMR_FIELD_ACCT_FLAGS) SET_AFLAGS(msg, info21.acct_flags, "userAccountControl"); IFSET(SAMR_FIELD_PARAMETERS) - SET_STRING(msg, info21.parameters, "userParameters"); + SET_PARAMETERS(msg, info21.parameters, "userParameters"); IFSET(SAMR_FIELD_COUNTRY_CODE) SET_UINT (msg, info21.country_code, "countryCode"); IFSET(SAMR_FIELD_CODE_PAGE) @@ -3472,7 +3507,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL IFSET(SAMR_FIELD_ACCT_FLAGS) SET_AFLAGS(msg, info23.info.acct_flags, "userAccountControl"); IFSET(SAMR_FIELD_PARAMETERS) - SET_STRING(msg, info23.info.parameters, "userParameters"); + SET_PARAMETERS(msg, info23.info.parameters, "userParameters"); IFSET(SAMR_FIELD_COUNTRY_CODE) SET_UINT (msg, info23.info.country_code, "countryCode"); IFSET(SAMR_FIELD_CODE_PAGE) @@ -3528,7 +3563,7 @@ static NTSTATUS dcesrv_samr_SetUserInfo(struct dcesrv_call_state *dce_call, TALL IFSET(SAMR_FIELD_ACCT_FLAGS) SET_AFLAGS(msg, info25.info.acct_flags, "userAccountControl"); IFSET(SAMR_FIELD_PARAMETERS) - SET_STRING(msg, info25.info.parameters, "userParameters"); + SET_PARAMETERS(msg, info25.info.parameters, "userParameters"); IFSET(SAMR_FIELD_COUNTRY_CODE) SET_UINT (msg, info25.info.country_code, "countryCode"); IFSET(SAMR_FIELD_CODE_PAGE) @@ -3645,7 +3680,7 @@ static NTSTATUS dcesrv_samr_GetGroupsForUser(struct dcesrv_call_state *dce_call, } } - r->out.rids = array; + *r->out.rids = array; return NT_STATUS_OK; } @@ -3803,65 +3838,65 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo(struct dcesrv_call_state *dce_call, count += 1; } - r->out.total_size = count; + *r->out.total_size = count; if (r->in.start_idx >= count) { - r->out.returned_size = 0; + *r->out.returned_size = 0; switch(r->in.level) { case 1: - r->out.info.info1.count = r->out.returned_size; - r->out.info.info1.entries = NULL; + r->out.info->info1.count = *r->out.returned_size; + r->out.info->info1.entries = NULL; break; case 2: - r->out.info.info2.count = r->out.returned_size; - r->out.info.info2.entries = NULL; + r->out.info->info2.count = *r->out.returned_size; + r->out.info->info2.entries = NULL; break; case 3: - r->out.info.info3.count = r->out.returned_size; - r->out.info.info3.entries = NULL; + r->out.info->info3.count = *r->out.returned_size; + r->out.info->info3.entries = NULL; break; case 4: - r->out.info.info4.count = r->out.returned_size; - r->out.info.info4.entries = NULL; + r->out.info->info4.count = *r->out.returned_size; + r->out.info->info4.entries = NULL; break; case 5: - r->out.info.info5.count = r->out.returned_size; - r->out.info.info5.entries = NULL; + r->out.info->info5.count = *r->out.returned_size; + r->out.info->info5.entries = NULL; break; } } else { - r->out.returned_size = MIN(count - r->in.start_idx, + *r->out.returned_size = MIN(count - r->in.start_idx, r->in.max_entries); switch(r->in.level) { case 1: - r->out.info.info1.count = r->out.returned_size; - r->out.info.info1.entries = + r->out.info->info1.count = *r->out.returned_size; + r->out.info->info1.entries = &(entriesGeneral[r->in.start_idx]); break; case 2: - r->out.info.info2.count = r->out.returned_size; - r->out.info.info2.entries = + r->out.info->info2.count = *r->out.returned_size; + r->out.info->info2.entries = &(entriesFull[r->in.start_idx]); break; case 3: - r->out.info.info3.count = r->out.returned_size; - r->out.info.info3.entries = + r->out.info->info3.count = *r->out.returned_size; + r->out.info->info3.entries = &(entriesFullGroup[r->in.start_idx]); break; case 4: - r->out.info.info4.count = r->out.returned_size; - r->out.info.info4.entries = + r->out.info->info4.count = *r->out.returned_size; + r->out.info->info4.entries = &(entriesAscii[r->in.start_idx]); break; case 5: - r->out.info.info5.count = r->out.returned_size; - r->out.info.info5.entries = + r->out.info->info5.count = *r->out.returned_size; + r->out.info->info5.entries = &(entriesAscii[r->in.start_idx]); break; } } - return (r->out.returned_size < (count - r->in.start_idx)) ? + return (*r->out.returned_size < (count - r->in.start_idx)) ? STATUS_MORE_ENTRIES : NT_STATUS_OK; } @@ -3905,18 +3940,18 @@ static NTSTATUS dcesrv_samr_GetUserPwInfo(struct dcesrv_call_state *dce_call, TA struct dcesrv_handle *h; struct samr_account_state *a_state; - ZERO_STRUCT(r->out.info); + ZERO_STRUCTP(r->out.info); DCESRV_PULL_HANDLE(h, r->in.user_handle, SAMR_HANDLE_USER); a_state = h->data; - r->out.info.min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, - a_state->domain_state->domain_dn, "minPwdLength", - NULL); - r->out.info.password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, - a_state->account_dn, - "pwdProperties", NULL); + r->out.info->min_password_length = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, + a_state->domain_state->domain_dn, "minPwdLength", + NULL); + r->out.info->password_properties = samdb_search_uint(a_state->sam_ctx, mem_ctx, 0, + a_state->account_dn, + "pwdProperties", NULL); return NT_STATUS_OK; } @@ -4003,11 +4038,10 @@ static NTSTATUS dcesrv_samr_QueryDomainInfo2(struct dcesrv_call_state *dce_call, ZERO_STRUCT(r1.out); r1.in.domain_handle = r->in.domain_handle; r1.in.level = r->in.level; - + r1.out.info = r->out.info; + status = dcesrv_samr_QueryDomainInfo(dce_call, mem_ctx, &r1); - r->out.info = r1.out.info; - return status; } @@ -4023,13 +4057,11 @@ static NTSTATUS dcesrv_samr_QueryUserInfo2(struct dcesrv_call_state *dce_call, T struct samr_QueryUserInfo r1; NTSTATUS status; - ZERO_STRUCT(r1.out); r1.in.user_handle = r->in.user_handle; r1.in.level = r->in.level; + r1.out.info = r->out.info; status = dcesrv_samr_QueryUserInfo(dce_call, mem_ctx, &r1); - - r->out.info = r1.out.info; return status; } @@ -4049,14 +4081,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo2(struct dcesrv_call_state *dce_call q.in.start_idx = r->in.start_idx; q.in.max_entries = r->in.max_entries; q.in.buf_size = r->in.buf_size; - ZERO_STRUCT(q.out); + q.out.total_size = r->out.total_size; + q.out.returned_size = r->out.returned_size; + q.out.info = r->out.info; result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q); - r->out.total_size = q.out.total_size; - r->out.returned_size = q.out.returned_size; - r->out.info = q.out.info; - return result; } @@ -4085,14 +4115,12 @@ static NTSTATUS dcesrv_samr_QueryDisplayInfo3(struct dcesrv_call_state *dce_call q.in.start_idx = r->in.start_idx; q.in.max_entries = r->in.max_entries; q.in.buf_size = r->in.buf_size; - ZERO_STRUCT(q.out); + q.out.total_size = r->out.total_size; + q.out.returned_size = r->out.returned_size; + q.out.info = r->out.info; result = dcesrv_samr_QueryDisplayInfo(dce_call, mem_ctx, &q); - r->out.total_size = q.out.total_size; - r->out.returned_size = q.out.returned_size; - r->out.info = q.out.info; - return result; } @@ -4133,7 +4161,7 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL const char * const attrs[] = {"minPwdLength", "pwdProperties", NULL }; struct ldb_context *sam_ctx; - ZERO_STRUCT(r->out.info); + ZERO_STRUCTP(r->out.info); sam_ctx = samdb_connect(mem_ctx, dce_call->event_ctx, dce_call->conn->dce_ctx->lp_ctx, dce_call->conn->auth_state.session_info); if (sam_ctx == NULL) { @@ -4151,8 +4179,8 @@ static NTSTATUS dcesrv_samr_GetDomPwInfo(struct dcesrv_call_state *dce_call, TAL return NT_STATUS_INTERNAL_DB_CORRUPTION; } - r->out.info.min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0); - r->out.info.password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1); + r->out.info->min_password_length = samdb_result_uint(msgs[0], "minPwdLength", 0); + r->out.info->password_properties = samdb_result_uint(msgs[0], "pwdProperties", 1); talloc_free(msgs); @@ -4262,9 +4290,9 @@ static NTSTATUS dcesrv_samr_Connect5(struct dcesrv_call_state *dce_call, TALLOC_ status = dcesrv_samr_Connect(dce_call, mem_ctx, &c); - r->out.info->info1.client_version = SAMR_CONNECT_AFTER_W2K; - r->out.info->info1.unknown2 = 0; - r->out.level = r->in.level; + r->out.info_out->info1.client_version = SAMR_CONNECT_AFTER_W2K; + r->out.info_out->info1.unknown2 = 0; + *r->out.level_out = r->in.level_in; return status; } @@ -4284,8 +4312,8 @@ static NTSTATUS dcesrv_samr_RidToSid(struct dcesrv_call_state *dce_call, TALLOC_ d_state = h->data; /* form the users SID */ - r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); - if (!r->out.sid) { + *r->out.sid = dom_sid_add_rid(mem_ctx, d_state->domain_sid, r->in.rid); + if (!*r->out.sid) { return NT_STATUS_NO_MEMORY; } diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 1eb6a4f37c..ff8215a673 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -352,7 +352,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call, uint8_t new_nt_hash[16], new_lm_hash[16]; struct samr_Password nt_verifier, lm_verifier; - ZERO_STRUCT(r->out); + *r->out.dominfo = NULL; + *r->out.reject = NULL; if (r->in.nt_password == NULL || r->in.nt_verifier == NULL) { @@ -495,8 +496,8 @@ failed: talloc_free(sam_ctx); reject = talloc(mem_ctx, struct samr_ChangeReject); - r->out.dominfo = dominfo; - r->out.reject = reject; + *r->out.dominfo = dominfo; + *r->out.reject = reject; if (reject == NULL) { return status; @@ -518,6 +519,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL struct samr_ChangePasswordUser2 *r) { struct samr_ChangePasswordUser3 r2; + struct samr_DomInfo1 *dominfo = NULL; + struct samr_ChangeReject *reject = NULL; r2.in.server = r->in.server; r2.in.account = r->in.account; @@ -527,6 +530,8 @@ NTSTATUS dcesrv_samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TAL r2.in.lm_password = r->in.lm_password; r2.in.lm_verifier = r->in.lm_verifier; r2.in.password3 = NULL; + r2.out.dominfo = &dominfo; + r2.out.reject = &reject; return dcesrv_samr_ChangePasswordUser3(dce_call, mem_ctx, &r2); } diff --git a/source4/rpc_server/service_rpc.c b/source4/rpc_server/service_rpc.c index f168614ad5..e526b17db1 100644 --- a/source4/rpc_server/service_rpc.c +++ b/source4/rpc_server/service_rpc.c @@ -287,12 +287,10 @@ static NTSTATUS dcesrv_add_ep_ncalrpc(struct dcesrv_context *dce_ctx, return status; } - -/* - add a socket address to the list of events, one event per dcerpc endpoint -*/ -static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_endpoint *e, - struct event_context *event_ctx, const struct model_ops *model_ops) +static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, + struct loadparm_context *lp_ctx, + struct dcesrv_endpoint *e, + struct event_context *event_ctx, const struct model_ops *model_ops) { struct dcesrv_socket_context *dcesrv_sock; NTSTATUS status; @@ -309,30 +307,16 @@ static NTSTATUS add_socket_rpc_pipe_iface(struct dcesrv_context *dce_ctx, struct dcesrv_sock->endpoint = e; dcesrv_sock->dcesrv_ctx = talloc_reference(dcesrv_sock, dce_ctx); - status = NT_STATUS_OK; -#if 0 - - status = stream_setup_smb_pipe(event_ctx, model_ops, &dcesrv_stream_ops, - e->ep_description->endpoint, dcesrv_sock); + status = stream_setup_named_pipe(event_ctx, lp_ctx, + model_ops, &dcesrv_stream_ops, + e->ep_description->endpoint, dcesrv_sock); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("service_setup_stream_socket(path=%s) failed - %s\n", + DEBUG(0,("stream_setup_named_pipe(pipe=%s) failed - %s\n", e->ep_description->endpoint, nt_errstr(status))); + return status; } -#endif - return status; -} -static NTSTATUS dcesrv_add_ep_np(struct dcesrv_context *dce_ctx, - struct loadparm_context *lp_ctx, - struct dcesrv_endpoint *e, - struct event_context *event_ctx, const struct model_ops *model_ops) -{ - NTSTATUS status; - - status = add_socket_rpc_pipe_iface(dce_ctx, e, event_ctx, model_ops); - NT_STATUS_NOT_OK_RETURN(status); - - return status; + return NT_STATUS_OK; } /* diff --git a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c index b4e08896e5..f33c49aa4e 100644 --- a/source4/rpc_server/srvsvc/dcesrv_srvsvc.c +++ b/source4/rpc_server/srvsvc/dcesrv_srvsvc.c @@ -1458,6 +1458,7 @@ static WERROR dcesrv_srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TA struct srvsvc_NetSrvGetInfo *r) { struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; + struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx); ZERO_STRUCTP(r->out.info); @@ -1487,8 +1488,8 @@ static WERROR dcesrv_srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TA info101->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc); W_ERROR_HAVE_NO_MEMORY(info101->server_name); - info101->version_major = dcesrv_common_get_version_major(mem_ctx, dce_ctx->lp_ctx); - info101->version_minor = dcesrv_common_get_version_minor(mem_ctx, dce_ctx->lp_ctx); + info101->version_major = server_info->version_major; + info101->version_minor = server_info->version_minor; info101->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); info101->comment = talloc_strdup(mem_ctx, lp_serverstring(dce_ctx->lp_ctx)); W_ERROR_HAVE_NO_MEMORY(info101->comment); @@ -1507,8 +1508,8 @@ static WERROR dcesrv_srvsvc_NetSrvGetInfo(struct dcesrv_call_state *dce_call, TA info102->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, r->in.server_unc); W_ERROR_HAVE_NO_MEMORY(info102->server_name); - info102->version_major = dcesrv_common_get_version_major(mem_ctx, dce_ctx->lp_ctx); - info102->version_minor = dcesrv_common_get_version_minor(mem_ctx, dce_ctx->lp_ctx); + info102->version_major = server_info->version_major; + info102->version_minor = server_info->version_minor; info102->server_type = dcesrv_common_get_server_type(mem_ctx, dce_call->event_ctx, dce_ctx); info102->comment = talloc_strdup(mem_ctx, lp_serverstring(dce_ctx->lp_ctx)); W_ERROR_HAVE_NO_MEMORY(info102->comment); diff --git a/source4/rpc_server/wkssvc/dcesrv_wkssvc.c b/source4/rpc_server/wkssvc/dcesrv_wkssvc.c index cbade288ca..e23485aea9 100644 --- a/source4/rpc_server/wkssvc/dcesrv_wkssvc.c +++ b/source4/rpc_server/wkssvc/dcesrv_wkssvc.c @@ -23,6 +23,7 @@ #include "rpc_server/dcerpc_server.h" #include "librpc/gen_ndr/ndr_wkssvc.h" #include "rpc_server/common/common.h" +#include "param/param.h" /* wkssvc_NetWkstaGetInfo @@ -31,6 +32,7 @@ static WERROR dcesrv_wkssvc_NetWkstaGetInfo(struct dcesrv_call_state *dce_call, struct wkssvc_NetWkstaGetInfo *r) { struct dcesrv_context *dce_ctx = dce_call->conn->dce_ctx; + struct dcerpc_server_info *server_info = lp_dcerpc_server_info(mem_ctx, dce_ctx->lp_ctx); ZERO_STRUCT(r->out); r->out.info = talloc_zero(mem_ctx, union wkssvc_NetWkstaInfo); @@ -49,10 +51,10 @@ static WERROR dcesrv_wkssvc_NetWkstaGetInfo(struct dcesrv_call_state *dce_call, info100->platform_id = dcesrv_common_get_platform_id(mem_ctx, dce_ctx); info100->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, NULL); W_ERROR_HAVE_NO_MEMORY(info100->server_name); - info100->domain_name = dcesrv_common_get_domain_name(mem_ctx, dce_ctx); + info100->domain_name = talloc_reference(mem_ctx, server_info->domain_name); W_ERROR_HAVE_NO_MEMORY(info100->domain_name); - info100->version_major = dcesrv_common_get_version_major(mem_ctx, dce_ctx->lp_ctx); - info100->version_minor = dcesrv_common_get_version_minor(mem_ctx, dce_ctx->lp_ctx); + info100->version_major = server_info->version_major; + info100->version_minor = server_info->version_minor; r->out.info->info100 = info100; return WERR_OK; @@ -67,10 +69,10 @@ static WERROR dcesrv_wkssvc_NetWkstaGetInfo(struct dcesrv_call_state *dce_call, info101->platform_id = dcesrv_common_get_platform_id(mem_ctx, dce_ctx); info101->server_name = dcesrv_common_get_server_name(mem_ctx, dce_ctx, NULL); W_ERROR_HAVE_NO_MEMORY(info101->server_name); - info101->domain_name = dcesrv_common_get_domain_name(mem_ctx, dce_ctx); + info101->domain_name = talloc_reference(mem_ctx, server_info->domain_name); W_ERROR_HAVE_NO_MEMORY(info101->domain_name); - info101->version_major = dcesrv_common_get_version_major(mem_ctx, dce_ctx->lp_ctx); - info101->version_minor = dcesrv_common_get_version_minor(mem_ctx, dce_ctx->lp_ctx); + info101->version_major = server_info->version_major; + info101->version_minor = server_info->version_minor; info101->lan_root = dcesrv_common_get_lan_root(mem_ctx, dce_ctx); r->out.info->info101 = info101; diff --git a/source4/script/installheader.pl b/source4/script/installheader.pl index 6b10bde65f..5be3434a5c 100755 --- a/source4/script/installheader.pl +++ b/source4/script/installheader.pl @@ -64,6 +64,8 @@ sub install_header($$) if (/^#include \"(.*)\"/) { print OUT "#include <" . rewrite_include("$src:$lineno", $1) . ">\n"; + } elsif (/^#if _SAMBA_BUILD_ == 4/) { + print OUT "#if 1\n"; } else { print OUT $_; } diff --git a/source4/selftest/knownfail b/source4/selftest/knownfail index f99db4fb1b..9649a1f644 100644 --- a/source4/selftest/knownfail +++ b/source4/selftest/knownfail @@ -35,6 +35,7 @@ rpc.netlogon.*.DsRAddressToSitenamesW rpc.netlogon.*.DsRAddressToSitenamesExW rpc.netlogon.*.GetPassword rpc.netlogon.*.GetTrustPasswords +rpc.netlogon.*.DatabaseRedo base.charset.*.Testing partial surrogate .*net.api.delshare.* # DelShare isn't implemented yet rap.*netservergetinfo diff --git a/source4/smb_server/smb/negprot.c b/source4/smb_server/smb/negprot.c index 00ff3862f5..71ee82d162 100644 --- a/source4/smb_server/smb/negprot.c +++ b/source4/smb_server/smb/negprot.c @@ -353,7 +353,7 @@ static void reply_nt1(struct smbsrv_request *req, uint16_t choice) nt_status = gensec_server_start(req->smb_conn, req->smb_conn->connection->event.ctx, - req->smb_conn->lp_ctx, + lp_gensec_settings(req->smb_conn, req->smb_conn->lp_ctx), req->smb_conn->connection->msg_ctx, &gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index a12bbd5cec..0767a187e5 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -365,7 +365,7 @@ static void sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup *se status = gensec_server_start(req, req->smb_conn->connection->event.ctx, - req->smb_conn->lp_ctx, + lp_gensec_settings(req, req->smb_conn->lp_ctx), req->smb_conn->connection->msg_ctx, &gensec_ctx); if (!NT_STATUS_IS_OK(status)) { @@ -382,7 +382,7 @@ static void sesssetup_spnego(struct smbsrv_request *req, union smb_sesssetup *se status = gensec_start_mech_by_oid(gensec_ctx, req->smb_conn->negotiate.oid); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Failed to start GENSEC %s server code: %s\n", - gensec_get_name_by_oid(req->smb_conn->negotiate.oid), nt_errstr(status))); + gensec_get_name_by_oid(gensec_ctx, req->smb_conn->negotiate.oid), nt_errstr(status))); goto failed; } diff --git a/source4/smb_server/smb2/negprot.c b/source4/smb_server/smb2/negprot.c index 49a2d12ef4..03e5c9356d 100644 --- a/source4/smb_server/smb2/negprot.c +++ b/source4/smb_server/smb2/negprot.c @@ -42,7 +42,7 @@ static NTSTATUS smb2srv_negprot_secblob(struct smb2srv_request *req, DATA_BLOB * nt_status = gensec_server_start(req, req->smb_conn->connection->event.ctx, - req->smb_conn->lp_ctx, + lp_gensec_settings(req, req->smb_conn->lp_ctx), req->smb_conn->connection->msg_ctx, &gensec_security); if (!NT_STATUS_IS_OK(nt_status)) { diff --git a/source4/smb_server/smb2/sesssetup.c b/source4/smb_server/smb2/sesssetup.c index 9f8765d6e9..176be0b3ea 100644 --- a/source4/smb_server/smb2/sesssetup.c +++ b/source4/smb_server/smb2/sesssetup.c @@ -126,7 +126,7 @@ static void smb2srv_sesssetup_backend(struct smb2srv_request *req, union smb_ses status = gensec_server_start(req, req->smb_conn->connection->event.ctx, - req->smb_conn->lp_ctx, + lp_gensec_settings(req, req->smb_conn->lp_ctx), req->smb_conn->connection->msg_ctx, &gensec_ctx); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/smbd/config.mk b/source4/smbd/config.mk index b5babd4d69..63105d368c 100644 --- a/source4/smbd/config.mk +++ b/source4/smbd/config.mk @@ -2,11 +2,12 @@ [SUBSYSTEM::service] PRIVATE_DEPENDENCIES = \ - MESSAGING samba-socket + MESSAGING samba-socket NDR_NAMED_PIPE_AUTH service_OBJ_FILES = $(addprefix $(smbdsrcdir)/, \ service.o \ service_stream.o \ + service_named_pipe.o \ service_task.o) $(eval $(call proto_header_template,$(smbdsrcdir)/service_proto.h,$(service_OBJ_FILES:.o=.c))) diff --git a/source4/smbd/service_named_pipe.c b/source4/smbd/service_named_pipe.c new file mode 100644 index 0000000000..b2b102c01f --- /dev/null +++ b/source4/smbd/service_named_pipe.c @@ -0,0 +1,366 @@ +/* + Unix SMB/CIFS implementation. + + helper functions for NAMED PIPE servers + + Copyright (C) Stefan (metze) Metzmacher 2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "lib/socket/socket.h" +#include "smbd/service.h" +#include "param/param.h" +#include "auth/session.h" +#include "lib/stream/packet.h" +#include "librpc/gen_ndr/ndr_named_pipe_auth.h" +#include "system/passwd.h" + +struct named_pipe_socket { + const char *pipe_name; + const char *pipe_path; + const struct stream_server_ops *ops; + void *private_data; +}; + +struct named_pipe_connection { + struct stream_connection *connection; + struct packet_context *packet; + const struct named_pipe_socket *pipe_sock; + NTSTATUS status; +}; + +static void named_pipe_handover_connection(void *private_data) +{ + struct named_pipe_connection *pipe_conn = talloc_get_type( + private_data, struct named_pipe_connection); + struct stream_connection *conn = pipe_conn->connection; + + EVENT_FD_NOT_WRITEABLE(conn->event.fde); + + if (!NT_STATUS_IS_OK(pipe_conn->status)) { + stream_terminate_connection(conn, nt_errstr(pipe_conn->status)); + return; + } + + /* + * remove the named_pipe layer together with its packet layer + */ + conn->ops = pipe_conn->pipe_sock->ops; + conn->private = pipe_conn->pipe_sock->private_data; + talloc_free(pipe_conn); + + /* we're now ready to start receiving events on this stream */ + EVENT_FD_READABLE(conn->event.fde); + + /* + * hand over to the real pipe implementation, + * now that we have setup the transport session_info + */ + conn->ops->accept_connection(conn); + + DEBUG(10,("named_pipe_handover_connection[%s]: succeeded\n", + conn->ops->name)); +} + +static NTSTATUS named_pipe_recv_auth_request(void *private_data, + DATA_BLOB req_blob) +{ + struct named_pipe_connection *pipe_conn = talloc_get_type( + private_data, struct named_pipe_connection); + struct stream_connection *conn = pipe_conn->connection; + enum ndr_err_code ndr_err; + struct named_pipe_auth_req req; + union netr_Validation val; + struct auth_serversupplied_info *server_info; + struct named_pipe_auth_rep rep; + DATA_BLOB rep_blob; + NTSTATUS status; + + /* + * make sure nothing happens on the socket untill the + * real implemenation takes over + */ + packet_recv_disable(pipe_conn->packet); + + /* + * TODO: check it's a root (uid == 0) pipe + */ + + ZERO_STRUCT(rep); + rep.level = 0; + rep.status = NT_STATUS_INTERNAL_ERROR; + + DEBUG(10,("named_pipe_auth: req_blob.length[%u]\n", + (unsigned int)req_blob.length)); + dump_data(10, req_blob.data, req_blob.length); + + /* parse the passed credentials */ + ndr_err = ndr_pull_struct_blob_all( + &req_blob, + pipe_conn, + lp_iconv_convenience(conn->lp_ctx), + &req, + (ndr_pull_flags_fn_t)ndr_pull_named_pipe_auth_req); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + rep.status = ndr_map_error2ntstatus(ndr_err); + DEBUG(2, ("Could not unmarshall named_pipe_auth_req: %s\n", + nt_errstr(rep.status))); + goto reply; + } + + if (strcmp(NAMED_PIPE_AUTH_MAGIC, req.magic) != 0) { + DEBUG(2, ("named_pipe_auth_req: invalid magic '%s' != %s\n", + req.magic, NAMED_PIPE_AUTH_MAGIC)); + rep.status = NT_STATUS_INVALID_PARAMETER; + goto reply; + } + + switch (req.level) { + case 0: + /* + * anon connection, we don't create a session info + * and leave it NULL + */ + rep.level = 0; + rep.status = NT_STATUS_OK; + break; + case 1: + val.sam3 = &req.info.info1; + + rep.level = 1; + rep.status = make_server_info_netlogon_validation(pipe_conn, + "TODO", + 3, &val, + &server_info); + if (!NT_STATUS_IS_OK(rep.status)) { + DEBUG(2, ("make_server_info_netlogon_validation returned " + "%s\n", nt_errstr(rep.status))); + goto reply; + } + + /* setup the session_info on the connection */ + rep.status = auth_generate_session_info(conn, + conn->event.ctx, + conn->lp_ctx, + server_info, + &conn->session_info); + if (!NT_STATUS_IS_OK(rep.status)) { + DEBUG(2, ("auth_generate_session_info failed: %s\n", + nt_errstr(rep.status))); + goto reply; + } + + break; + default: + DEBUG(2, ("named_pipe_auth_req: unknown level %u\n", + req.level)); + rep.level = 0; + rep.status = NT_STATUS_INVALID_LEVEL; + goto reply; + } + +reply: + /* create the output */ + ndr_err = ndr_push_struct_blob(&rep_blob, pipe_conn, + lp_iconv_convenience(conn->lp_ctx), + &rep, + (ndr_push_flags_fn_t)ndr_push_named_pipe_auth_rep); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + status = ndr_map_error2ntstatus(ndr_err); + DEBUG(2, ("Could not marshall named_pipe_auth_rep: %s\n", + nt_errstr(status))); + return status; + } + + pipe_conn->status = rep.status; + + DEBUG(10,("named_pipe_auth reply[%u]\n", rep_blob.length)); + dump_data(10, rep_blob.data, rep_blob.length); + status = packet_send_callback(pipe_conn->packet, rep_blob, + named_pipe_handover_connection, + pipe_conn); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, ("packet_send_callback returned %s\n", + nt_errstr(status))); + return status; + } + + return NT_STATUS_OK; +} + +/* + called when a pipe socket becomes readable +*/ +static void named_pipe_recv(struct stream_connection *conn, uint16_t flags) +{ + struct named_pipe_connection *pipe_conn = talloc_get_type( + conn->private, struct named_pipe_connection); + + DEBUG(10,("named_pipe_recv\n")); + + packet_recv(pipe_conn->packet); +} + +/* + called when a pipe socket becomes writable +*/ +static void named_pipe_send(struct stream_connection *conn, uint16_t flags) +{ + struct named_pipe_connection *pipe_conn = talloc_get_type( + conn->private, struct named_pipe_connection); + + packet_queue_run(pipe_conn->packet); +} + +/* + handle socket recv errors +*/ +static void named_pipe_recv_error(void *private_data, NTSTATUS status) +{ + struct named_pipe_connection *pipe_conn = talloc_get_type( + private_data, struct named_pipe_connection); + + stream_terminate_connection(pipe_conn->connection, nt_errstr(status)); +} + +static NTSTATUS named_pipe_full_request(void *private, DATA_BLOB blob, size_t *size) +{ + if (blob.length < 8) { + return STATUS_MORE_ENTRIES; + } + + if (memcmp(NAMED_PIPE_AUTH_MAGIC, &blob.data[4], 4) != 0) { + DEBUG(0,("named_pipe_full_request: wrong protocol\n")); + *size = blob.length; + /* the error will be handled in named_pipe_recv_auth_request */ + return NT_STATUS_OK; + } + + *size = 4 + RIVAL(blob.data, 0); + if (*size > blob.length) { + return STATUS_MORE_ENTRIES; + } + + return NT_STATUS_OK; +} + +static void named_pipe_accept(struct stream_connection *conn) +{ + struct named_pipe_socket *pipe_sock = talloc_get_type( + conn->private, struct named_pipe_socket); + struct named_pipe_connection *pipe_conn; + + DEBUG(5,("named_pipe_accept\n")); + + pipe_conn = talloc_zero(conn, struct named_pipe_connection); + if (!pipe_conn) { + stream_terminate_connection(conn, "out of memory"); + return; + } + + pipe_conn->packet = packet_init(pipe_conn); + if (!pipe_conn->packet) { + stream_terminate_connection(conn, "out of memory"); + return; + } + packet_set_private(pipe_conn->packet, pipe_conn); + packet_set_socket(pipe_conn->packet, conn->socket); + packet_set_callback(pipe_conn->packet, named_pipe_recv_auth_request); + packet_set_full_request(pipe_conn->packet, named_pipe_full_request); + packet_set_error_handler(pipe_conn->packet, named_pipe_recv_error); + packet_set_event_context(pipe_conn->packet, conn->event.ctx); + packet_set_fde(pipe_conn->packet, conn->event.fde); + packet_set_serialise(pipe_conn->packet); + packet_set_initial_read(pipe_conn->packet, 8); + + pipe_conn->pipe_sock = pipe_sock; + + pipe_conn->connection = conn; + conn->private = pipe_conn; +} + +static const struct stream_server_ops named_pipe_stream_ops = { + .name = "named_pipe", + .accept_connection = named_pipe_accept, + .recv_handler = named_pipe_recv, + .send_handler = named_pipe_send, +}; + +NTSTATUS stream_setup_named_pipe(struct event_context *event_context, + struct loadparm_context *lp_ctx, + const struct model_ops *model_ops, + const struct stream_server_ops *stream_ops, + const char *pipe_name, + void *private_data) +{ + char *dirname; + struct named_pipe_socket *pipe_sock; + NTSTATUS status = NT_STATUS_NO_MEMORY;; + + pipe_sock = talloc(event_context, struct named_pipe_socket); + if (pipe_sock == NULL) { + goto fail; + } + + /* remember the details about the pipe */ + pipe_sock->pipe_name = talloc_strdup(pipe_sock, pipe_name); + if (pipe_sock->pipe_name == NULL) { + goto fail; + } + + dirname = talloc_asprintf(pipe_sock, "%s/np", lp_ncalrpc_dir(lp_ctx)); + if (dirname == NULL) { + goto fail; + } + + if (!directory_create_or_exist(dirname, geteuid(), 0700)) { + status = map_nt_error_from_unix(errno); + goto fail; + } + + if (strncmp(pipe_name, "\\pipe\\", 6) == 0) { + pipe_name += 6; + } + + pipe_sock->pipe_path = talloc_asprintf(pipe_sock, "%s/%s", dirname, + pipe_name); + if (pipe_sock->pipe_path == NULL) { + goto fail; + } + + talloc_free(dirname); + + pipe_sock->ops = stream_ops; + pipe_sock->private_data = talloc_reference(pipe_sock, private_data); + + status = stream_setup_socket(event_context, + lp_ctx, + model_ops, + &named_pipe_stream_ops, + "unix", + pipe_sock->pipe_path, + NULL, + NULL, + pipe_sock); + if (!NT_STATUS_IS_OK(status)) { + goto fail; + } + return NT_STATUS_OK; + + fail: + talloc_free(pipe_sock); + return status; +} diff --git a/source4/torture/auth/ntlmssp.c b/source4/torture/auth/ntlmssp.c index 1e8b339997..e62b150a4b 100644 --- a/source4/torture/auth/ntlmssp.c +++ b/source4/torture/auth/ntlmssp.c @@ -23,6 +23,7 @@ #include "auth/ntlmssp/ntlmssp.h" #include "lib/cmdline/popt_common.h" #include "torture/torture.h" +#include "param/param.h" static bool torture_ntlmssp_self_check(struct torture_context *tctx) { @@ -34,7 +35,7 @@ static bool torture_ntlmssp_self_check(struct torture_context *tctx) torture_assert_ntstatus_ok(tctx, gensec_client_start(mem_ctx, &gensec_security, - tctx->ev, tctx->lp_ctx), + tctx->ev, lp_gensec_settings(tctx, tctx->lp_ctx)), "gensec client start"); gensec_set_credentials(gensec_security, cmdline_credentials); @@ -89,7 +90,7 @@ static bool torture_ntlmssp_self_check(struct torture_context *tctx) torture_assert_ntstatus_ok(tctx, gensec_client_start(mem_ctx, &gensec_security, - tctx->ev, tctx->lp_ctx), + tctx->ev, lp_gensec_settings(tctx, tctx->lp_ctx)), "Failed to start GENSEC for NTLMSSP"); gensec_set_credentials(gensec_security, cmdline_credentials); diff --git a/source4/torture/basic/base.c b/source4/torture/basic/base.c index f2b7b9b225..ea7b6c08fd 100644 --- a/source4/torture/basic/base.c +++ b/source4/torture/basic/base.c @@ -57,7 +57,8 @@ static struct smbcli_state *open_nbt_connection(struct torture_context *tctx) if (!smbcli_socket_connect(cli, host, lp_smb_ports(tctx->lp_ctx), tctx->ev, lp_resolve_context(tctx->lp_ctx), &options, - lp_iconv_convenience(tctx->lp_ctx))) { + lp_iconv_convenience(tctx->lp_ctx), + lp_socket_options(tctx->lp_ctx))) { torture_comment(tctx, "Failed to connect with %s\n", host); goto failed; } @@ -1449,14 +1450,8 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) const char *os2_fname = ".+,;=[]."; const char *dname = "samba3_errordir"; union smb_open io; - TALLOC_CTX *mem_ctx = talloc_init("samba3_errorpaths"); NTSTATUS status; - if (mem_ctx == NULL) { - torture_comment(tctx, "talloc_init failed\n"); - return false; - } - nt_status_support = lp_nt_status_support(tctx->lp_ctx); if (!lp_set_cmdline(tctx->lp_ctx, "nt status support", "yes")) { @@ -1505,14 +1500,14 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) io.ntcreatex.in.security_flags = 0; io.ntcreatex.in.fname = dname; - status = smb_raw_open(cli_nt->tree, mem_ctx, &io); + status = smb_raw_open(cli_nt->tree, tctx, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { torture_comment(tctx, "(%s) incorrect status %s should be %s\n", __location__, nt_errstr(status), nt_errstr(NT_STATUS_OBJECT_NAME_COLLISION)); goto fail; } - status = smb_raw_open(cli_dos->tree, mem_ctx, &io); + status = smb_raw_open(cli_dos->tree, tctx, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) { torture_comment(tctx, "(%s) incorrect status %s should be %s\n", __location__, nt_errstr(status), @@ -1562,7 +1557,7 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) } io.ntcreatex.in.create_options = NTCREATEX_OPTIONS_DIRECTORY; - status = smb_raw_open(cli_nt->tree, mem_ctx, &io); + status = smb_raw_open(cli_nt->tree, tctx, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_COLLISION)) { torture_comment(tctx, "(%s) incorrect status %s should be %s\n", __location__, nt_errstr(status), @@ -1570,7 +1565,7 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) goto fail; } - status = smb_raw_open(cli_dos->tree, mem_ctx, &io); + status = smb_raw_open(cli_dos->tree, tctx, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRfilexists))) { torture_comment(tctx, "(%s) incorrect status %s should be %s\n", __location__, nt_errstr(status), @@ -1643,7 +1638,7 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) io.ntcreatex.in.fname = fname; io.ntcreatex.in.flags = 0; - status = smb_raw_open(cli_nt->tree, mem_ctx, &io); + status = smb_raw_open(cli_nt->tree, tctx, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) { torture_comment(tctx, "ntcreate as dir gave %s, " "expected NT_STATUS_NOT_A_DIRECTORY\n", @@ -1655,7 +1650,7 @@ static bool torture_samba3_errorpaths(struct torture_context *tctx) smbcli_close(cli_nt->tree, io.ntcreatex.out.file.fnum); } - status = smb_raw_open(cli_dos->tree, mem_ctx, &io); + status = smb_raw_open(cli_dos->tree, tctx, &io); if (!NT_STATUS_EQUAL(status, NT_STATUS_DOS(ERRDOS, ERRbaddirectory))) { torture_comment(tctx, "ntcreate as dir gave %s, " diff --git a/source4/torture/basic/misc.c b/source4/torture/basic/misc.c index 89e7169883..f11b90f448 100644 --- a/source4/torture/basic/misc.c +++ b/source4/torture/basic/misc.c @@ -817,11 +817,13 @@ static struct composite_context *torture_connect_async( smb->in.dest_host=talloc_strdup(mem_ctx,host); smb->in.service=talloc_strdup(mem_ctx,share); smb->in.dest_ports=lp_smb_ports(tctx->lp_ctx); + smb->in.socket_options = lp_socket_options(tctx->lp_ctx); smb->in.called_name = strupper_talloc(mem_ctx, host); smb->in.service_type=NULL; smb->in.credentials=cmdline_credentials; smb->in.fallback_to_anonymous=false; smb->in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); + smb->in.gensec_settings = lp_gensec_settings(mem_ctx, tctx->lp_ctx); smb->in.workgroup=workgroup; lp_smbcli_options(tctx->lp_ctx, &smb->in.options); lp_smbcli_session_options(tctx->lp_ctx, &smb->in.session_options); diff --git a/source4/torture/basic/secleak.c b/source4/torture/basic/secleak.c index ca1fd444d9..3fdd9a9bbd 100644 --- a/source4/torture/basic/secleak.c +++ b/source4/torture/basic/secleak.c @@ -44,8 +44,9 @@ static bool try_failed_login(struct torture_context *tctx, struct smbcli_state * setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); - setup.in.credentials = cli_credentials_init(session); + setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); + cli_credentials_set_conf(setup.in.credentials, tctx->lp_ctx); cli_credentials_set_domain(setup.in.credentials, "INVALID-DOMAIN", CRED_SPECIFIED); cli_credentials_set_username(setup.in.credentials, "INVALID-USERNAME", CRED_SPECIFIED); diff --git a/source4/torture/config.mk b/source4/torture/config.mk index 211d09756d..8b12f36f95 100644 --- a/source4/torture/config.mk +++ b/source4/torture/config.mk @@ -1,5 +1,5 @@ [SUBSYSTEM::TORTURE_UTIL] -PRIVATE_DEPENDENCIES = LIBCLI_RAW LIBPYTHON smbcalls PROVISION +PRIVATE_DEPENDENCIES = LIBCLI_RAW PUBLIC_DEPENDENCIES = POPT_CREDENTIALS TORTURE_UTIL_OBJ_FILES = $(addprefix $(torturesrcdir)/, util_smb.o) @@ -212,7 +212,8 @@ INIT_FUNCTION = torture_net_init PRIVATE_DEPENDENCIES = \ LIBSAMBA-NET \ POPT_CREDENTIALS \ - torture_rpc + torture_rpc \ + PROVISION # End SUBSYSTEM TORTURE_NET ################################# diff --git a/source4/torture/gentest.c b/source4/torture/gentest.c index aefed23f51..02eecd7f40 100644 --- a/source4/torture/gentest.c +++ b/source4/torture/gentest.c @@ -227,22 +227,28 @@ static bool connect_servers(struct event_context *ev, if (options.smb2) { status = smb2_connect(NULL, servers[i].server_name, + lp_smb_ports(lp_ctx), servers[i].share_name, lp_resolve_context(lp_ctx), servers[i].credentials, &servers[i].smb2_tree[j], - ev, &smb_options); + ev, &smb_options, + lp_socket_options(lp_ctx), + lp_gensec_settings(lp_ctx, lp_ctx) + ); } else { status = smbcli_tree_full_connection(NULL, &servers[i].smb_tree[j], servers[i].server_name, lp_smb_ports(lp_ctx), servers[i].share_name, "A:", + lp_socket_options(lp_ctx), servers[i].credentials, lp_resolve_context(lp_ctx), ev, &smb_options, &smb_session_options, - lp_iconv_convenience(lp_ctx)); + lp_iconv_convenience(lp_ctx), + lp_gensec_settings(lp_ctx, lp_ctx)); } if (!NT_STATUS_IS_OK(status)) { printf("Failed to connect to \\\\%s\\%s - %s\n", diff --git a/source4/torture/libnet/libnet_domain.c b/source4/torture/libnet/libnet_domain.c index 7d5be368c2..3c28d1a019 100644 --- a/source4/torture/libnet/libnet_domain.c +++ b/source4/torture/libnet/libnet_domain.c @@ -35,12 +35,13 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *domname, - uint32_t *access_mask, struct dom_sid **sid) + uint32_t *access_mask, struct dom_sid **sid_p) { NTSTATUS status; struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; printf("connecting\n"); @@ -59,6 +60,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; printf("domain lookup on %s\n", domname->string); @@ -70,7 +72,7 @@ static bool test_opendomain_samr(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r3.in.connect_handle = &h; r3.in.access_mask = *access_mask; - r3.in.sid = *sid = r2.out.sid; + r3.in.sid = *sid_p = *r2.out.sid; r3.out.domain_handle = &domain_handle; printf("opening domain\n"); diff --git a/source4/torture/libnet/libnet_group.c b/source4/torture/libnet/libnet_group.c index 12b8167a86..9c9ecfd525 100644 --- a/source4/torture/libnet/libnet_group.c +++ b/source4/torture/libnet/libnet_group.c @@ -42,12 +42,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_String names[2]; uint32_t rid; struct policy_handle group_handle; + struct samr_Ids rids, types; names[0].string = groupname; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; printf("group account lookup '%s'\n", groupname); @@ -57,7 +60,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -139,6 +142,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; printf("connecting\n"); @@ -155,6 +159,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; printf("domain lookup on %s\n", domname->string); @@ -166,7 +171,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r3.in.sid = r2.out.sid; + r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; printf("opening domain\n"); diff --git a/source4/torture/libnet/libnet_user.c b/source4/torture/libnet/libnet_user.c index 6d3e682976..18007dccad 100644 --- a/source4/torture/libnet/libnet_user.c +++ b/source4/torture/libnet/libnet_user.c @@ -40,12 +40,15 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_String names[2]; uint32_t rid; struct policy_handle user_handle; + struct samr_Ids rids, types; names[0].string = username; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; printf("user account lookup '%s'\n", username); @@ -55,7 +58,7 @@ static bool test_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -92,6 +95,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; printf("connecting\n"); @@ -108,6 +112,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; printf("domain lookup on %s\n", domname->string); @@ -119,7 +124,7 @@ static bool test_opendomain(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r3.in.sid = r2.out.sid; + r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; printf("opening domain\n"); diff --git a/source4/torture/libnet/utils.c b/source4/torture/libnet/utils.c index 54c5f2c29c..942540c80e 100644 --- a/source4/torture/libnet/utils.c +++ b/source4/torture/libnet/utils.c @@ -32,12 +32,13 @@ bool test_opendomain(struct torture_context *tctx, struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle *handle, struct lsa_String *domname, - struct dom_sid2 *sid) + struct dom_sid2 *sid_p) { NTSTATUS status; struct policy_handle h, domain_handle; struct samr_Connect r1; struct samr_LookupDomain r2; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain r3; torture_comment(tctx, "connecting\n"); @@ -51,6 +52,7 @@ bool test_opendomain(struct torture_context *tctx, r2.in.connect_handle = &h; r2.in.domain_name = domname; + r2.out.sid = &sid; torture_comment(tctx, "domain lookup on %s\n", domname->string); @@ -59,7 +61,7 @@ bool test_opendomain(struct torture_context *tctx, r3.in.connect_handle = &h; r3.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r3.in.sid = r2.out.sid; + r3.in.sid = *r2.out.sid; r3.out.domain_handle = &domain_handle; torture_comment(tctx, "opening domain\n"); @@ -68,7 +70,7 @@ bool test_opendomain(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "OpenDomain failed"); *handle = domain_handle; - *sid = *r2.out.sid; + *sid_p = **r2.out.sid; return true; } @@ -84,19 +86,22 @@ bool test_user_cleanup(struct torture_context *tctx, struct dcerpc_pipe *p, struct lsa_String names[2]; uint32_t rid; struct policy_handle user_handle; + struct samr_Ids rids, types; names[0].string = name; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; torture_comment(tctx, "user account lookup '%s'\n", name); status = dcerpc_samr_LookupNames(p, mem_ctx, &r1); torture_assert_ntstatus_ok(tctx, status, "LookupNames failed"); - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -174,12 +179,15 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct lsa_String names[2]; uint32_t rid; struct policy_handle group_handle; + struct samr_Ids rids, types; names[0].string = name; r1.in.domain_handle = domain_handle; r1.in.num_names = 1; r1.in.names = names; + r1.out.rids = &rids; + r1.out.types = &types; printf("group account lookup '%s'\n", name); @@ -189,7 +197,7 @@ bool test_group_cleanup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - rid = r1.out.rids.ids[0]; + rid = r1.out.rids->ids[0]; r2.in.domain_handle = domain_handle; r2.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; diff --git a/source4/torture/local/config.mk b/source4/torture/local/config.mk index def391ba4e..46d5e38e67 100644 --- a/source4/torture/local/config.mk +++ b/source4/torture/local/config.mk @@ -14,7 +14,8 @@ PRIVATE_DEPENDENCIES = \ TORTURE_UTIL \ TORTURE_NDR \ share \ - torture_registry + torture_registry \ + PROVISION # End SUBSYSTEM TORTURE_LOCAL ################################# diff --git a/source4/torture/locktest.c b/source4/torture/locktest.c index 819fbe072b..18c4156cc3 100644 --- a/source4/torture/locktest.c +++ b/source4/torture/locktest.c @@ -164,10 +164,12 @@ static struct smbcli_state *connect_one(struct event_context *ev, server, lp_smb_ports(lp_ctx), share, NULL, + lp_socket_options(lp_ctx), servers[snum], lp_resolve_context(lp_ctx), ev, &options, &session_options, - lp_iconv_convenience(lp_ctx)); + lp_iconv_convenience(lp_ctx), + lp_gensec_settings(mem_ctx, lp_ctx)); if (!NT_STATUS_IS_OK(status)) { sleep(2); } diff --git a/source4/torture/locktest2.c b/source4/torture/locktest2.c index e7cbf13c74..cb435c7b55 100644 --- a/source4/torture/locktest2.c +++ b/source4/torture/locktest2.c @@ -144,6 +144,7 @@ static struct smbcli_state *connect_one(TALLOC_CTX *mem_ctx, char *share, const char **ports, struct smb_options *options, struct smb_options *session_options, + struct gensec_settings *gensec_settings, struct event_context *ev) { struct smbcli_state *c; @@ -173,7 +174,7 @@ static struct smbcli_state *connect_one(TALLOC_CTX *mem_ctx, nt_status = smbcli_full_connection(NULL, &c, myname, server_n, ports, share, NULL, username, lp_workgroup(), password, ev, - options, session_options); + options, session_options, gensec_settings); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(0, ("smbcli_full_connection failed with error %s\n", nt_errstr(nt_status))); return NULL; @@ -192,6 +193,7 @@ static void reconnect(TALLOC_CTX *mem_ctx, const char **ports, struct smbcli_options *options, struct smbcli_session_options *session_options, + struct gensec_settings *gensec_settings, struct event_context *ev, char *share1, char *share2) { @@ -211,7 +213,7 @@ static void reconnect(TALLOC_CTX *mem_ctx, smbcli_ulogoff(cli[server][conn]); talloc_free(cli[server][conn]); } - cli[server][conn] = connect_one(mem_ctx, share[server], ports, options, session_options, ev); + cli[server][conn] = connect_one(mem_ctx, share[server], ports, options, session_options, gensec_settings, ev); if (!cli[server][conn]) { DEBUG(0,("Failed to connect to %s\n", share[server])); exit(1); @@ -362,6 +364,7 @@ static void test_locks(TALLOC_CTX *mem_ctx, char *share1, char *share2, const char **ports, struct smbcli_options *options, struct smbcli_session_options *session_options, + struct gensec_settings *gensec_settings, struct event_context *ev) { struct smbcli_state *cli[NSERVERS][NCONNECTIONS]; @@ -391,7 +394,7 @@ static void test_locks(TALLOC_CTX *mem_ctx, char *share1, char *share2, recorded[n].needed = true; } - reconnect(mem_ctx, cli, nfs, fnum, ports, options, session_options, ev, share1, share2); + reconnect(mem_ctx, cli, nfs, fnum, ports, options, session_options, gensec_settings, ev, share1, share2); open_files(cli, nfs, fnum); n = retest(cli, nfs, fnum, numops); @@ -429,7 +432,7 @@ static void test_locks(TALLOC_CTX *mem_ctx, char *share1, char *share2, } close_files(cli, nfs, fnum); - reconnect(mem_ctx, cli, nfs, fnum, ports, options, session_options, ev, share1, share2); + reconnect(mem_ctx, cli, nfs, fnum, ports, options, session_options, gensec_settings, ev, share1, share2); open_files(cli, nfs, fnum); showall = true; n1 = retest(cli, nfs, fnum, n); @@ -567,8 +570,9 @@ static void usage(void) locking_init(1); lp_smbcli_options(lp_ctx, &options); lp_smbcli_session_options(lp_ctx, &session_options); - test_locks(mem_ctx, share1, share2, nfspath1, nfspath2, lp_smb_ports(lp_ctx), - &options, &session_options, ev); + test_locks(mem_ctx, share1, share2, nfspath1, nfspath2, + lp_smb_ports(lp_ctx), + &options, &session_options, lp_gensec_settings(lp_ctx), ev); return(0); } diff --git a/source4/torture/masktest.c b/source4/torture/masktest.c index 14d597666e..9ff790c2b0 100644 --- a/source4/torture/masktest.c +++ b/source4/torture/masktest.c @@ -76,9 +76,11 @@ static struct smbcli_state *connect_one(struct resolve_context *resolve_ctx, struct event_context *ev, TALLOC_CTX *mem_ctx, char *share, const char **ports, + const char *socket_options, struct smbcli_options *options, struct smbcli_session_options *session_options, - struct smb_iconv_convenience *iconv_convenience) + struct smb_iconv_convenience *iconv_convenience, + struct gensec_settings *gensec_settings) { struct smbcli_state *c; char *server; @@ -96,9 +98,11 @@ static struct smbcli_state *connect_one(struct resolve_context *resolve_ctx, server, ports, share, NULL, + socket_options, cmdline_credentials, resolve_ctx, ev, options, session_options, - iconv_convenience); + iconv_convenience, + gensec_settings); if (!NT_STATUS_IS_OK(status)) { return NULL; @@ -368,8 +372,10 @@ static void usage(poptContext pc) lp_smbcli_session_options(lp_ctx, &session_options); cli = connect_one(lp_resolve_context(lp_ctx), ev, mem_ctx, share, - lp_smb_ports(lp_ctx), &options, &session_options, - lp_iconv_convenience(lp_ctx)); + lp_smb_ports(lp_ctx), lp_socket_options(lp_ctx), + &options, &session_options, + lp_iconv_convenience(lp_ctx), + lp_gensec_settings(mem_ctx, lp_ctx)); if (!cli) { DEBUG(0,("Failed to connect to %s\n", share)); exit(1); diff --git a/source4/torture/raw/acls.c b/source4/torture/raw/acls.c index a07da8a36b..48dec6e561 100644 --- a/source4/torture/raw/acls.c +++ b/source4/torture/raw/acls.c @@ -1088,7 +1088,7 @@ static bool test_owner_bits(struct torture_context *tctx, { NTSTATUS status; union smb_open io; - const char *fname = BASEDIR "\\generic.txt"; + const char *fname = BASEDIR "\\test_owner_bits.txt"; bool ret = true; int fnum = -1, i; union smb_fileinfo q; @@ -1181,6 +1181,11 @@ static bool test_owner_bits(struct torture_context *tctx, CHECK_ACCESS_FLAGS(io.ntcreatex.out.file.fnum, bit | SEC_FILE_READ_ATTRIBUTE); smbcli_close(cli->tree, io.ntcreatex.out.file.fnum); } else { + if (NT_STATUS_IS_OK(status)) { + printf("open succeeded with access mask 0x%08x of " + "expected 0x%08x - should fail\n", + bit, expected_bits); + } CHECK_STATUS(status, NT_STATUS_ACCESS_DENIED); } } @@ -1405,7 +1410,9 @@ static bool test_inheritance(struct torture_context *tctx, if (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT)) { if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) { - printf("Expected default sd at %d - got:\n", i); + printf("Expected default sd:\n"); + NDR_PRINT_DEBUG(security_descriptor, sd_def); + printf("at %d - got:\n", i); NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd); } goto check_dir; @@ -1450,7 +1457,9 @@ static bool test_inheritance(struct torture_context *tctx, (!(test_flags[i].parent_flags & SEC_ACE_FLAG_OBJECT_INHERIT) || (test_flags[i].parent_flags & SEC_ACE_FLAG_NO_PROPAGATE_INHERIT))) { if (!security_descriptor_equal(q.query_secdesc.out.sd, sd_def)) { - printf("Expected default sd for dir at %d - got:\n", i); + printf("Expected default sd for dir at %d:\n", i); + NDR_PRINT_DEBUG(security_descriptor, sd_def); + printf("got:\n"); NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd); } continue; @@ -1464,7 +1473,7 @@ static bool test_inheritance(struct torture_context *tctx, !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee, sd_orig->owner_sid) || q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) { - printf("Bad sd in child dir at %d (parent 0x%x)\n", + printf("(CI & NP) Bad sd in child dir at %d (parent 0x%x)\n", i, test_flags[i].parent_flags); NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd); ret = false; @@ -1482,7 +1491,7 @@ static bool test_inheritance(struct torture_context *tctx, q.query_secdesc.out.sd->dacl->aces[0].flags != 0 || q.query_secdesc.out.sd->dacl->aces[1].flags != (test_flags[i].dir_flags | SEC_ACE_FLAG_INHERIT_ONLY)) { - printf("Bad sd in child dir at %d (parent 0x%x)\n", + printf("(CI) Bad sd in child dir at %d (parent 0x%x)\n", i, test_flags[i].parent_flags); NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd); ret = false; @@ -1495,8 +1504,8 @@ static bool test_inheritance(struct torture_context *tctx, !dom_sid_equal(&q.query_secdesc.out.sd->dacl->aces[0].trustee, creator_owner) || q.query_secdesc.out.sd->dacl->aces[0].flags != test_flags[i].dir_flags) { - printf("Bad sd in child dir at %d (parent 0x%x)\n", - i, test_flags[i].parent_flags); + printf("(0) Bad sd in child dir at %d (parent 0x%x)\n", + i, test_flags[i].parent_flags); NDR_PRINT_DEBUG(security_descriptor, q.query_secdesc.out.sd); ret = false; continue; diff --git a/source4/torture/raw/composite.c b/source4/torture/raw/composite.c index 16de4308bb..79ae41dafb 100644 --- a/source4/torture/raw/composite.c +++ b/source4/torture/raw/composite.c @@ -164,6 +164,7 @@ static bool test_fetchfile(struct smbcli_state *cli, struct torture_context *tct io2.in.filename = fname; io2.in.resolve_ctx = lp_resolve_context(tctx->lp_ctx); io2.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); + io2.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); lp_smbcli_options(tctx->lp_ctx, &io2.in.options); lp_smbcli_session_options(tctx->lp_ctx, &io2.in.session_options); @@ -347,6 +348,7 @@ static bool test_fsinfo(struct smbcli_state *cli, struct torture_context *tctx) io1.in.dest_host = torture_setting_string(tctx, "host", NULL); io1.in.dest_ports = lp_smb_ports(tctx->lp_ctx); + io1.in.socket_options = lp_socket_options(tctx->lp_ctx); io1.in.called_name = torture_setting_string(tctx, "host", NULL); io1.in.service = torture_setting_string(tctx, "share", NULL); io1.in.service_type = "A:"; @@ -354,6 +356,7 @@ static bool test_fsinfo(struct smbcli_state *cli, struct torture_context *tctx) io1.in.workgroup = lp_workgroup(tctx->lp_ctx); io1.in.level = RAW_QFS_OBJECTID_INFORMATION; io1.in.iconv_convenience = lp_iconv_convenience(tctx->lp_ctx); + io1.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); printf("testing parallel queryfsinfo [Object ID] with %d ops\n", torture_numops); diff --git a/source4/torture/raw/context.c b/source4/torture/raw/context.c index 450ad0f260..a9d36b7788 100644 --- a/source4/torture/raw/context.c +++ b/source4/torture/raw/context.c @@ -74,6 +74,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) struct smbcli_tree *tree; struct smb_composite_sesssetup setup; struct smb_composite_sesssetup setups[15]; + struct gensec_settings *gensec_settings; union smb_open io; union smb_write wr; union smb_close cl; @@ -92,6 +93,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) printf("create a second security context on the same transport\n"); lp_smbcli_session_options(tctx->lp_ctx, &options); + gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); session = smbcli_session_init(cli->transport, tctx, false, options); @@ -100,6 +102,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) setup.in.workgroup = lp_workgroup(tctx->lp_ctx); setup.in.credentials = cmdline_credentials; + setup.in.gensec_settings = gensec_settings; status = smb_composite_sesssetup(session, &setup); CHECK_STATUS(status, NT_STATUS_OK); @@ -142,7 +145,6 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) setup.in.workgroup = lp_workgroup(tctx->lp_ctx); setup.in.credentials = cmdline_credentials; - status = smb_composite_sesssetup(session3, &setup); CHECK_STATUS(status, NT_STATUS_LOGON_FAILURE); @@ -233,6 +235,7 @@ static bool test_session(struct smbcli_state *cli, struct torture_context *tctx) setups[i].in.workgroup = lp_workgroup(tctx->lp_ctx); setups[i].in.credentials = cmdline_credentials; + setups[i].in.gensec_settings = gensec_settings; sessions[i] = smbcli_session_init(cli->transport, tctx, false, options); composite_contexts[i] = smb_composite_sesssetup_send(sessions[i], &setups[i]); @@ -402,6 +405,7 @@ static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context * setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); setup.in.credentials = cmdline_credentials; + setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); status = smb_composite_sesssetup(session1, &setup); CHECK_STATUS(status, NT_STATUS_OK); session1->vuid = setup.out.vuid; @@ -458,6 +462,7 @@ static bool test_tree_ulogoff(struct smbcli_state *cli, struct torture_context * setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); setup.in.credentials = cmdline_credentials; + setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); status = smb_composite_sesssetup(session2, &setup); CHECK_STATUS(status, NT_STATUS_OK); session2->vuid = setup.out.vuid; @@ -657,8 +662,8 @@ static bool test_pid_2sess(struct smbcli_state *cli, struct torture_context *tct setup.in.sesskey = cli->transport->negotiate.sesskey; setup.in.capabilities = cli->transport->negotiate.capabilities; /* ignored in secondary session setup, except by our libs, which care about the extended security bit */ setup.in.workgroup = lp_workgroup(tctx->lp_ctx); - setup.in.credentials = cmdline_credentials; + setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); status = smb_composite_sesssetup(session, &setup); CHECK_STATUS(status, NT_STATUS_OK); diff --git a/source4/torture/raw/lock.c b/source4/torture/raw/lock.c index dbe071c9ad..2d1eae3a69 100644 --- a/source4/torture/raw/lock.c +++ b/source4/torture/raw/lock.c @@ -598,6 +598,7 @@ static bool test_async(struct torture_context *tctx, setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = lp_workgroup(tctx->lp_ctx); setup.in.credentials = cmdline_credentials; + setup.in.gensec_settings = lp_gensec_settings(tctx, tctx->lp_ctx); status = smb_composite_sesssetup(session, &setup); CHECK_STATUS(status, NT_STATUS_OK); session->vuid = setup.out.vuid; diff --git a/source4/torture/raw/lockbench.c b/source4/torture/raw/lockbench.c index a6dce8a926..dce21ebe71 100644 --- a/source4/torture/raw/lockbench.c +++ b/source4/torture/raw/lockbench.c @@ -188,6 +188,8 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te, io->in.dest_host = state->dest_host; io->in.dest_ports = state->dest_ports; + io->in.gensec_settings = lp_gensec_settings(state->mem_ctx, state->tctx->lp_ctx); + io->in.socket_options = lp_socket_options(state->tctx->lp_ctx); io->in.called_name = state->called_name; io->in.service = share; io->in.service_type = state->service_type; diff --git a/source4/torture/raw/openbench.c b/source4/torture/raw/openbench.c index ec94637445..2440649e7f 100644 --- a/source4/torture/raw/openbench.c +++ b/source4/torture/raw/openbench.c @@ -130,12 +130,14 @@ static void reopen_connection(struct event_context *ev, struct timed_event *te, io->in.dest_host = state->dest_host; io->in.dest_ports = state->dest_ports; + io->in.socket_options = lp_socket_options(state->tctx->lp_ctx); io->in.called_name = state->called_name; io->in.service = share; io->in.service_type = state->service_type; io->in.credentials = cmdline_credentials; io->in.fallback_to_anonymous = false; io->in.workgroup = lp_workgroup(state->tctx->lp_ctx); + io->in.gensec_settings = lp_gensec_settings(state->mem_ctx, state->tctx->lp_ctx); lp_smbcli_options(state->tctx->lp_ctx, &io->in.options); lp_smbcli_session_options(state->tctx->lp_ctx, &io->in.session_options); diff --git a/source4/torture/raw/oplock.c b/source4/torture/raw/oplock.c index 46b41e51a0..4ffb24eb03 100644 --- a/source4/torture/raw/oplock.c +++ b/source4/torture/raw/oplock.c @@ -187,10 +187,11 @@ static bool open_connection_no_level2_oplocks(struct torture_context *tctx, torture_setting_string(tctx, "host", NULL), lp_smb_ports(tctx->lp_ctx), torture_setting_string(tctx, "share", NULL), - NULL, cmdline_credentials, + NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, - lp_iconv_convenience(tctx->lp_ctx)); + lp_iconv_convenience(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("Failed to open connection - %s\n", nt_errstr(status)); return false; diff --git a/source4/torture/raw/raw.c b/source4/torture/raw/raw.c index 0a7fc3ebfd..138f263106 100644 --- a/source4/torture/raw/raw.c +++ b/source4/torture/raw/raw.c @@ -71,6 +71,7 @@ NTSTATUS torture_raw_init(void) torture_suite_add_simple_test(suite, "SAMBA3ROOTDIRFID", torture_samba3_rootdirfid); torture_suite_add_simple_test(suite, "SAMBA3CHECKFSP", torture_samba3_checkfsp); + torture_suite_add_simple_test(suite, "SAMBA3OPLOCKLOGOFF", torture_samba3_oplock_logoff); torture_suite_add_simple_test(suite, "SAMBA3BADPATH", torture_samba3_badpath); torture_suite_add_simple_test(suite, "SAMBA3CASEINSENSITIVE", torture_samba3_caseinsensitive); diff --git a/source4/torture/raw/samba3misc.c b/source4/torture/raw/samba3misc.c index 27b4d42dd8..8cdccb3906 100644 --- a/source4/torture/raw/samba3misc.c +++ b/source4/torture/raw/samba3misc.c @@ -889,3 +889,83 @@ bool torture_samba3_rootdirfid(struct torture_context *tctx) return ret; } +bool torture_samba3_oplock_logoff(struct torture_context *tctx) +{ + struct smbcli_state *cli; + NTSTATUS status; + uint16_t fnum1; + union smb_open io; + const char *fname = "testfile"; + bool ret = false; + struct smbcli_request *req; + struct smb_echo echo_req; + + if (!torture_open_connection(&cli, tctx, 0)) { + ret = false; + goto done; + } + + smbcli_unlink(cli->tree, fname); + + ZERO_STRUCT(io); + io.generic.level = RAW_OPEN_NTCREATEX; + io.ntcreatex.in.flags = NTCREATEX_FLAGS_EXTENDED; + io.ntcreatex.in.root_fid = 0; + io.ntcreatex.in.security_flags = 0; + io.ntcreatex.in.access_mask = + SEC_STD_SYNCHRONIZE | SEC_FILE_EXECUTE; + io.ntcreatex.in.alloc_size = 0; + io.ntcreatex.in.file_attr = FILE_ATTRIBUTE_NORMAL; + io.ntcreatex.in.share_access = NTCREATEX_SHARE_ACCESS_NONE; + io.ntcreatex.in.open_disposition = NTCREATEX_DISP_OPEN_IF; + io.ntcreatex.in.create_options = 0; + io.ntcreatex.in.fname = "testfile"; + status = smb_raw_open(cli->tree, tctx, &io); + if (!NT_STATUS_IS_OK(status)) { + d_printf("first smb_open failed: %s\n", nt_errstr(status)); + ret = false; + goto done; + } + fnum1 = io.ntcreatex.out.file.fnum; + + /* + * Create a conflicting open, causing the one-second delay + */ + + req = smb_raw_open_send(cli->tree, &io); + if (req == NULL) { + d_printf("smb_raw_open_send failed\n"); + ret = false; + goto done; + } + + /* + * Pull the VUID from under that request. As of Nov 3, 2008 all Samba3 + * versions (3.0, 3.2 and master) would spin sending ERRinvuid errors + * as long as the client is still connected. + */ + + status = smb_raw_ulogoff(cli->session); + + if (!NT_STATUS_IS_OK(status)) { + d_printf("ulogoff failed: %s\n", nt_errstr(status)); + ret = false; + goto done; + } + + echo_req.in.repeat_count = 1; + echo_req.in.size = 1; + echo_req.in.data = (uint8_t *)""; + + status = smb_raw_echo(cli->session->transport, &echo_req); + if (!NT_STATUS_IS_OK(status)) { + d_printf("smb_raw_echo returned %s\n", + nt_errstr(status)); + ret = false; + goto done; + } + + ret = true; + done: + return ret; +} diff --git a/source4/torture/raw/tconrate.c b/source4/torture/raw/tconrate.c index 9e75301828..0109b65481 100644 --- a/source4/torture/raw/tconrate.c +++ b/source4/torture/raw/tconrate.c @@ -100,10 +100,11 @@ static int fork_tcon_client(struct torture_context *tctx, status = smbcli_full_connection(NULL, &cli, host, lp_smb_ports(tctx->lp_ctx), share, - NULL, cmdline_credentials, + NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, - lp_iconv_convenience(tctx->lp_ctx)); + lp_iconv_convenience(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", diff --git a/source4/torture/rpc/join.c b/source4/torture/rpc/join.c index a6bb53a759..b0c122c1b6 100644 --- a/source4/torture/rpc/join.c +++ b/source4/torture/rpc/join.c @@ -39,10 +39,12 @@ bool torture_rpc_join(struct torture_context *torture) status = smbcli_full_connection(tj, &cli, host, lp_smb_ports(torture->lp_ctx), "IPC$", NULL, + lp_socket_options(torture->lp_ctx), machine_account, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("%s failed to connect to IPC$ with workstation credentials\n", TORTURE_NETBIOS_NAME)); @@ -66,10 +68,12 @@ bool torture_rpc_join(struct torture_context *torture) status = smbcli_full_connection(tj, &cli, host, lp_smb_ports(torture->lp_ctx), "IPC$", NULL, + lp_socket_options(torture->lp_ctx), machine_account, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("%s failed to connect to IPC$ with workstation credentials\n", TORTURE_NETBIOS_NAME)); diff --git a/source4/torture/rpc/mgmt.c b/source4/torture/rpc/mgmt.c index fed432f31c..7f618ab776 100644 --- a/source4/torture/rpc/mgmt.c +++ b/source4/torture/rpc/mgmt.c @@ -128,7 +128,7 @@ static bool test_inq_princ_name(struct dcerpc_pipe *p, continue; } if (W_ERROR_IS_OK(r.out.result)) { - const char *name = gensec_get_name_by_authtype(i); + const char *name = gensec_get_name_by_authtype(NULL, i); ret = true; if (name) { printf("\tprinciple name for proto %u (%s) is '%s'\n", diff --git a/source4/torture/rpc/netlogon.c b/source4/torture/rpc/netlogon.c index 96cab0bf02..953f9d126d 100644 --- a/source4/torture/rpc/netlogon.c +++ b/source4/torture/rpc/netlogon.c @@ -32,8 +32,10 @@ #include "../lib/crypto/crypto.h" #include "libcli/auth/libcli_auth.h" #include "librpc/gen_ndr/ndr_netlogon_c.h" +#include "librpc/gen_ndr/ndr_netlogon.h" #include "librpc/gen_ndr/ndr_lsa_c.h" #include "param/param.h" +#include "libcli/security/security.h" #define TEST_MACHINE_NAME "torturetest" @@ -831,6 +833,538 @@ static bool test_DatabaseDeltas(struct torture_context *tctx, return true; } +static bool test_DatabaseRedo(struct torture_context *tctx, + struct dcerpc_pipe *p, + struct cli_credentials *machine_credentials) +{ + NTSTATUS status; + struct netr_DatabaseRedo r; + struct creds_CredentialState *creds; + struct netr_Authenticator credential; + struct netr_Authenticator return_authenticator; + struct netr_DELTA_ENUM_ARRAY *delta_enum_array = NULL; + struct netr_ChangeLogEntry e; + struct dom_sid null_sid, *sid; + int i,d; + + ZERO_STRUCT(null_sid); + + sid = dom_sid_parse_talloc(tctx, "S-1-5-21-1111111111-2222222222-333333333-500"); + + { + + struct { + uint32_t rid; + uint16_t flags; + uint8_t db_index; + uint8_t delta_type; + struct dom_sid sid; + const char *name; + NTSTATUS expected_error; + uint32_t expected_num_results; + uint8_t expected_delta_type_1; + uint8_t expected_delta_type_2; + const char *comment; + } changes[] = { + + /* SAM_DATABASE_DOMAIN */ + + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_MODIFY_COUNT, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, + .expected_num_results = 0, + .comment = "NETR_DELTA_MODIFY_COUNT" + }, + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = 0, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DOMAIN, + .comment = "NULL DELTA" + }, + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_DOMAIN, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DOMAIN, + .comment = "NETR_DELTA_DOMAIN" + }, + { + .rid = DOMAIN_RID_ADMINISTRATOR, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_USER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_USER, + .comment = "NETR_DELTA_USER by rid 500" + }, + { + .rid = DOMAIN_RID_GUEST, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_USER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_USER, + .comment = "NETR_DELTA_USER by rid 501" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_USER, + .sid = *sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_USER, + .comment = "NETR_DELTA_USER by sid and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_USER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_USER, + .comment = "NETR_DELTA_USER by null_sid and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_NAME_INCLUDED, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_USER, + .sid = null_sid, + .name = "administrator", + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_USER, + .comment = "NETR_DELTA_USER by name 'administrator'" + }, + { + .rid = DOMAIN_RID_ADMINS, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_GROUP, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 2, + .expected_delta_type_1 = NETR_DELTA_GROUP, + .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER, + .comment = "NETR_DELTA_GROUP by rid 512" + }, + { + .rid = DOMAIN_RID_ADMINS, + .flags = 0, + .db_index = SAM_DATABASE_DOMAIN, + .delta_type = NETR_DELTA_GROUP_MEMBER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 2, + .expected_delta_type_1 = NETR_DELTA_GROUP, + .expected_delta_type_2 = NETR_DELTA_GROUP_MEMBER, + .comment = "NETR_DELTA_GROUP_MEMBER by rid 512" + }, + + + /* SAM_DATABASE_BUILTIN */ + + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_MODIFY_COUNT, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, + .expected_num_results = 0, + .comment = "NETR_DELTA_MODIFY_COUNT" + }, + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_DOMAIN, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DOMAIN, + .comment = "NETR_DELTA_DOMAIN" + }, + { + .rid = DOMAIN_RID_ADMINISTRATOR, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_USER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_USER, + .comment = "NETR_DELTA_USER by rid 500" + }, + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_USER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_USER, + .comment = "NETR_DELTA_USER" + }, + { + .rid = 544, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_ALIAS, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 2, + .expected_delta_type_1 = NETR_DELTA_ALIAS, + .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER, + .comment = "NETR_DELTA_ALIAS by rid 544" + }, + { + .rid = 544, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_ALIAS_MEMBER, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 2, + .expected_delta_type_1 = NETR_DELTA_ALIAS, + .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER, + .comment = "NETR_DELTA_ALIAS_MEMBER by rid 544" + }, + { + .rid = 544, + .flags = 0, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = 0, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DOMAIN, + .comment = "NULL DELTA by rid 544" + }, + { + .rid = 544, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = 0, + .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"), + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DOMAIN, + .comment = "NULL DELTA by rid 544 sid S-1-5-32-544 and flags" + }, + { + .rid = 544, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_ALIAS, + .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"), + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 2, + .expected_delta_type_1 = NETR_DELTA_ALIAS, + .expected_delta_type_2 = NETR_DELTA_ALIAS_MEMBER, + .comment = "NETR_DELTA_ALIAS by rid 544 and sid S-1-5-32-544 and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_BUILTIN, + .delta_type = NETR_DELTA_ALIAS, + .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32-544"), + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_ALIAS, + .comment = "NETR_DELTA_ALIAS by sid S-1-5-32-544 and flags" + }, + + /* SAM_DATABASE_PRIVS */ + + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = 0, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_ACCESS_DENIED, + .expected_num_results = 0, + .comment = "NULL DELTA" + }, + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_MODIFY_COUNT, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, + .expected_num_results = 0, + .comment = "NETR_DELTA_MODIFY_COUNT" + }, + { + .rid = 0, + .flags = 0, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_POLICY, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_POLICY, + .comment = "NETR_DELTA_POLICY" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_POLICY, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_POLICY, + .comment = "NETR_DELTA_POLICY by null sid and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_POLICY, + .sid = *dom_sid_parse_talloc(tctx, "S-1-5-32"), + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_POLICY, + .comment = "NETR_DELTA_POLICY by sid S-1-5-32 and flags" + }, + { + .rid = DOMAIN_RID_ADMINISTRATOR, + .flags = 0, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_ACCOUNT, + .sid = null_sid, + .name = NULL, + .expected_error = NT_STATUS_SYNCHRONIZATION_REQUIRED, /* strange */ + .expected_num_results = 0, + .comment = "NETR_DELTA_ACCOUNT by rid 500" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_ACCOUNT, + .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"), + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_ACCOUNT, + .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED | + NETR_CHANGELOG_IMMEDIATE_REPL_REQUIRED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_ACCOUNT, + .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"), + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_ACCOUNT, + .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and 2 flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_SID_INCLUDED | + NETR_CHANGELOG_NAME_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_ACCOUNT, + .sid = *dom_sid_parse_talloc(tctx, "S-1-1-0"), + .name = NULL, + .expected_error = NT_STATUS_INVALID_PARAMETER, + .expected_num_results = 0, + .comment = "NETR_DELTA_ACCOUNT by sid S-1-1-0 and invalid flags" + }, + { + .rid = DOMAIN_RID_ADMINISTRATOR, + .flags = NETR_CHANGELOG_SID_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_ACCOUNT, + .sid = *sid, + .name = NULL, + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_ACCOUNT, + .comment = "NETR_DELTA_ACCOUNT by rid 500, sid and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_NAME_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_SECRET, + .sid = null_sid, + .name = "IsurelydontexistIhope", + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_DELETE_SECRET, + .comment = "NETR_DELTA_SECRET by name 'IsurelydontexistIhope' and flags" + }, + { + .rid = 0, + .flags = NETR_CHANGELOG_NAME_INCLUDED, + .db_index = SAM_DATABASE_PRIVS, + .delta_type = NETR_DELTA_SECRET, + .sid = null_sid, + .name = "G$BCKUPKEY_P", + .expected_error = NT_STATUS_OK, + .expected_num_results = 1, + .expected_delta_type_1 = NETR_DELTA_SECRET, + .comment = "NETR_DELTA_SECRET by name 'G$BCKUPKEY_P' and flags" + } + }; + + ZERO_STRUCT(return_authenticator); + + r.in.logon_server = talloc_asprintf(tctx, "\\\\%s", dcerpc_server_name(p)); + r.in.computername = TEST_MACHINE_NAME; + r.in.return_authenticator = &return_authenticator; + r.out.return_authenticator = &return_authenticator; + r.out.delta_enum_array = &delta_enum_array; + + for (d=0; d<3; d++) { + + const char *database; + + switch (d) { + case 0: + database = "SAM"; + break; + case 1: + database = "BUILTIN"; + break; + case 2: + database = "LSA"; + break; + default: + break; + } + + torture_comment(tctx, "Testing DatabaseRedo\n"); + + if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { + return false; + } + + for (i=0;i<ARRAY_SIZE(changes);i++) { + + if (d != changes[i].db_index) { + continue; + } + + creds_client_authenticator(creds, &credential); + + r.in.credential = &credential; + + e.serial_number1 = 0; + e.serial_number2 = 0; + e.object_rid = changes[i].rid; + e.flags = changes[i].flags; + e.db_index = changes[i].db_index; + e.delta_type = changes[i].delta_type; + + switch (changes[i].flags & (NETR_CHANGELOG_NAME_INCLUDED | NETR_CHANGELOG_SID_INCLUDED)) { + case NETR_CHANGELOG_SID_INCLUDED: + e.object.object_sid = changes[i].sid; + break; + case NETR_CHANGELOG_NAME_INCLUDED: + e.object.object_name = changes[i].name; + break; + default: + break; + } + + r.in.change_log_entry = e; + + torture_comment(tctx, "Testing DatabaseRedo with database %s and %s\n", + database, changes[i].comment); + + status = dcerpc_netr_DatabaseRedo(p, tctx, &r); + if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) { + return true; + } + + torture_assert_ntstatus_equal(tctx, status, changes[i].expected_error, changes[i].comment); + if (delta_enum_array) { + torture_assert_int_equal(tctx, + delta_enum_array->num_deltas, + changes[i].expected_num_results, + changes[i].comment); + if (delta_enum_array->num_deltas > 0) { + torture_assert_int_equal(tctx, + delta_enum_array->delta_enum[0].delta_type, + changes[i].expected_delta_type_1, + changes[i].comment); + } + if (delta_enum_array->num_deltas > 1) { + torture_assert_int_equal(tctx, + delta_enum_array->delta_enum[1].delta_type, + changes[i].expected_delta_type_2, + changes[i].comment); + } + } + + if (!creds_client_check(creds, &return_authenticator.cred)) { + torture_comment(tctx, "Credential chaining failed\n"); + if (!test_SetupCredentials(p, tctx, machine_credentials, &creds)) { + return false; + } + } + } + } + } + + return true; +} /* try a netlogon AccountDeltas @@ -1761,6 +2295,7 @@ struct torture_suite *torture_rpc_netlogon(TALLOC_CTX *mem_ctx) torture_rpc_tcase_add_test_creds(tcase, "GetDomainInfo", test_GetDomainInfo); torture_rpc_tcase_add_test_creds(tcase, "DatabaseSync", test_DatabaseSync); torture_rpc_tcase_add_test_creds(tcase, "DatabaseDeltas", test_DatabaseDeltas); + torture_rpc_tcase_add_test_creds(tcase, "DatabaseRedo", test_DatabaseRedo); torture_rpc_tcase_add_test_creds(tcase, "AccountDeltas", test_AccountDeltas); torture_rpc_tcase_add_test_creds(tcase, "AccountSync", test_AccountSync); torture_rpc_tcase_add_test(tcase, "GetDcName", test_GetDcName); diff --git a/source4/torture/rpc/remote_pac.c b/source4/torture/rpc/remote_pac.c index 1f03ad6396..0d18228563 100644 --- a/source4/torture/rpc/remote_pac.c +++ b/source4/torture/rpc/remote_pac.c @@ -92,7 +92,8 @@ static bool test_PACVerify(struct torture_context *tctx, torture_assert(tctx, msg_server_ctx != NULL, "Failed to init messaging context"); - status = gensec_client_start(tctx, &gensec_client_context, tctx->ev, tctx->lp_ctx); + status = gensec_client_start(tctx, &gensec_client_context, tctx->ev, + lp_gensec_settings(tctx, tctx->lp_ctx)); torture_assert_ntstatus_ok(tctx, status, "gensec_client_start (client) failed"); status = gensec_set_target_hostname(gensec_client_context, TEST_MACHINE_NAME); @@ -103,7 +104,9 @@ static bool test_PACVerify(struct torture_context *tctx, status = gensec_start_mech_by_sasl_name(gensec_client_context, "GSSAPI"); torture_assert_ntstatus_ok(tctx, status, "gensec_start_mech_by_sasl_name (client) failed"); - status = gensec_server_start(tctx, tctx->ev, tctx->lp_ctx, msg_server_ctx, &gensec_server_context); + status = gensec_server_start(tctx, tctx->ev, + lp_gensec_settings(tctx, tctx->lp_ctx), + msg_server_ctx, &gensec_server_context); torture_assert_ntstatus_ok(tctx, status, "gensec_server_start (server) failed"); status = gensec_set_credentials(gensec_server_context, credentials); diff --git a/source4/torture/rpc/rpc.c b/source4/torture/rpc/rpc.c index 3e5d2d4323..2fcf700c36 100644 --- a/source4/torture/rpc/rpc.c +++ b/source4/torture/rpc/rpc.c @@ -77,6 +77,8 @@ _PUBLIC_ NTSTATUS torture_rpc_connection(struct torture_context *tctx, NTSTATUS status; struct dcerpc_binding *binding; + dcerpc_init(tctx->lp_ctx); + status = torture_rpc_binding(tctx, &binding); if (NT_STATUS_IS_ERR(status)) return status; @@ -371,8 +373,6 @@ NTSTATUS torture_rpc_init(void) { struct torture_suite *suite = torture_suite_create(talloc_autofree_context(), "RPC"); - dcerpc_init(); - ndr_table_init(); torture_suite_add_simple_test(suite, "LSA", torture_rpc_lsa); diff --git a/source4/torture/rpc/samba3rpc.c b/source4/torture/rpc/samba3rpc.c index 93bcb3a1ea..1148262dfe 100644 --- a/source4/torture/rpc/samba3rpc.c +++ b/source4/torture/rpc/samba3rpc.c @@ -89,10 +89,13 @@ bool torture_bind_authcontext(struct torture_context *torture) status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), - "IPC$", NULL, cmdline_credentials, + "IPC$", NULL, + lp_socket_options(torture->lp_ctx), + cmdline_credentials, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -160,6 +163,7 @@ bool torture_bind_authcontext(struct torture_context *torture) setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = ""; setup.in.credentials = anon_creds; + setup.in.gensec_settings = lp_gensec_settings(torture, torture->lp_ctx); status = smb_composite_sesssetup(session2, &setup); if (!NT_STATUS_IS_OK(status)) { @@ -233,7 +237,7 @@ static bool bindtest(struct smbcli_state *cli, } status = dcerpc_bind_auth(lsa_pipe, &ndr_table_lsarpc, - credentials, lp_ctx, auth_type, auth_level, + credentials, lp_gensec_settings(lp_ctx, lp_ctx), auth_type, auth_level, NULL); if (!NT_STATUS_IS_OK(status)) { d_printf("dcerpc_bind_auth failed: %s\n", nt_errstr(status)); @@ -308,10 +312,13 @@ bool torture_bind_samba3(struct torture_context *torture) status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), - "IPC$", NULL, cmdline_credentials, + "IPC$", NULL, + lp_socket_options(torture->lp_ctx), + cmdline_credentials, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -348,7 +355,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, char **domain, struct dcerpc_pipe **result_pipe, struct policy_handle **result_handle, - struct dom_sid **sid) + struct dom_sid **sid_p) { struct dcerpc_pipe *samr_pipe; NTSTATUS status; @@ -358,7 +365,10 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, struct samr_Connect2 conn; struct samr_EnumDomains enumdom; uint32_t resume_handle = 0; + uint32_t num_entries = 0; + struct samr_SamArray *sam = NULL; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; int dom_idx; struct lsa_String domain_name; struct lsa_String user_name; @@ -384,7 +394,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, if (admin_creds != NULL) { status = dcerpc_bind_auth(samr_pipe, &ndr_table_samr, - admin_creds, lp_ctx, auth_type, auth_level, + admin_creds, lp_gensec_settings(lp_ctx, lp_ctx), auth_type, auth_level, NULL); if (!NT_STATUS_IS_OK(status)) { d_printf("dcerpc_bind_auth failed: %s\n", @@ -416,6 +426,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, enumdom.in.resume_handle = &resume_handle; enumdom.in.buf_size = (uint32_t)-1; enumdom.out.resume_handle = &resume_handle; + enumdom.out.num_entries = &num_entries; + enumdom.out.sam = &sam; status = dcerpc_samr_EnumDomains(samr_pipe, mem_ctx, &enumdom); if (!NT_STATUS_IS_OK(status)) { @@ -423,20 +435,21 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, goto fail; } - if (enumdom.out.num_entries != 2) { + if (*enumdom.out.num_entries != 2) { d_printf("samr_EnumDomains returned %d entries, expected 2\n", - enumdom.out.num_entries); + *enumdom.out.num_entries); status = NT_STATUS_UNSUCCESSFUL; goto fail; } - dom_idx = strequal(enumdom.out.sam->entries[0].name.string, + dom_idx = strequal(sam->entries[0].name.string, "builtin") ? 1:0; l.in.connect_handle = &conn_handle; - domain_name.string = enumdom.out.sam->entries[dom_idx].name.string; + domain_name.string = sam->entries[dom_idx].name.string; *domain = talloc_strdup(mem_ctx, domain_name.string); l.in.domain_name = &domain_name; + l.out.sid = &sid; status = dcerpc_samr_LookupDomain(samr_pipe, mem_ctx, &l); if (!NT_STATUS_IS_OK(status)) { @@ -446,7 +459,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, o.in.connect_handle = &conn_handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - o.in.sid = l.out.sid; + o.in.sid = *l.out.sid; o.out.domain_handle = &domain_handle; status = dcerpc_samr_OpenDomain(samr_pipe, mem_ctx, &o); @@ -470,10 +483,13 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, if (NT_STATUS_EQUAL(status, NT_STATUS_USER_EXISTS)) { struct samr_LookupNames ln; struct samr_OpenUser ou; + struct samr_Ids rids, types; ln.in.domain_handle = &domain_handle; ln.in.num_names = 1; ln.in.names = &user_name; + ln.out.rids = &rids; + ln.out.types = &types; status = dcerpc_samr_LookupNames(samr_pipe, mem_ctx, &ln); if (!NT_STATUS_IS_OK(status)) { @@ -484,7 +500,7 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, ou.in.domain_handle = &domain_handle; ou.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - user_rid = ou.in.rid = ln.out.rids.ids[0]; + user_rid = ou.in.rid = ln.out.rids->ids[0]; ou.out.user_handle = user_handle; status = dcerpc_samr_OpenUser(samr_pipe, mem_ctx, &ou); @@ -502,8 +518,8 @@ static NTSTATUS get_usr_handle(struct smbcli_state *cli, *result_pipe = samr_pipe; *result_handle = user_handle; - if (sid != NULL) { - *sid = dom_sid_add_rid(mem_ctx, l.out.sid, user_rid); + if (sid_p != NULL) { + *sid_p = dom_sid_add_rid(mem_ctx, *l.out.sid, user_rid); } return NT_STATUS_OK; @@ -548,6 +564,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, struct samr_SetUserInfo sui; struct samr_QueryUserInfo qui; union samr_UserInfo u_info; + union samr_UserInfo *info; DATA_BLOB session_key; @@ -590,6 +607,7 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, qui.in.user_handle = wks_handle; qui.in.level = 21; + qui.out.info = &info; status = dcerpc_samr_QueryUserInfo(samr_pipe, tmp_ctx, &qui); if (!NT_STATUS_IS_OK(status)) { @@ -597,14 +615,14 @@ static bool create_user(TALLOC_CTX *mem_ctx, struct smbcli_state *cli, goto done; } - qui.out.info->info21.allow_password_change = 0; - qui.out.info->info21.force_password_change = 0; - qui.out.info->info21.account_name.string = NULL; - qui.out.info->info21.rid = 0; - qui.out.info->info21.acct_expiry = 0; - qui.out.info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */ + info->info21.allow_password_change = 0; + info->info21.force_password_change = 0; + info->info21.account_name.string = NULL; + info->info21.rid = 0; + info->info21.acct_expiry = 0; + info->info21.fields_present = 0x81827fa; /* copy usrmgr.exe */ - u_info.info21 = qui.out.info->info21; + u_info.info21 = info->info21; sui.in.user_handle = wks_handle; sui.in.info = &u_info; sui.in.level = 21; @@ -714,9 +732,11 @@ static bool join3(struct smbcli_state *cli, { struct samr_QueryUserInfo q; + union samr_UserInfo *info; q.in.user_handle = wks_handle; q.in.level = 21; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -725,7 +745,7 @@ static bool join3(struct smbcli_state *cli, goto done; } - last_password_change = q.out.info->info21.last_password_change; + last_password_change = info->info21.last_password_change; } cli_credentials_set_domain(wks_creds, dom_name, CRED_SPECIFIED); @@ -823,9 +843,11 @@ static bool join3(struct smbcli_state *cli, { struct samr_QueryUserInfo q; + union samr_UserInfo *info; q.in.user_handle = wks_handle; q.in.level = 21; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(samr_pipe, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -836,7 +858,7 @@ static bool join3(struct smbcli_state *cli, if (use_level25) { if (last_password_change - == q.out.info->info21.last_password_change) { + == info->info21.last_password_change) { d_printf("(%s) last_password_change unchanged " "during join, level25 must change " "it\n", __location__); @@ -845,7 +867,7 @@ static bool join3(struct smbcli_state *cli, } else { if (last_password_change - != q.out.info->info21.last_password_change) { + != info->info21.last_password_change) { d_printf("(%s) last_password_change changed " "during join, level24 doesn't " "change it\n", __location__); @@ -1013,7 +1035,7 @@ static bool schan(struct smbcli_state *cli, #if 1 net_pipe->conn->flags |= (DCERPC_SIGN | DCERPC_SEAL); status = dcerpc_bind_auth(net_pipe, &ndr_table_netlogon, - wks_creds, lp_ctx, DCERPC_AUTH_TYPE_SCHANNEL, + wks_creds, lp_gensec_settings(lp_ctx, lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL, DCERPC_AUTH_LEVEL_PRIVACY, NULL); #else @@ -1244,10 +1266,13 @@ bool torture_netlogon_samba3(struct torture_context *torture) status = smbcli_full_connection(mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), - "IPC$", NULL, anon_creds, + "IPC$", NULL, + lp_socket_options(torture->lp_ctx), + anon_creds, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -1334,10 +1359,11 @@ static bool test_join3(struct torture_context *tctx, status = smbcli_full_connection(tctx, &cli, torture_setting_string(tctx, "host", NULL), lp_smb_ports(tctx->lp_ctx), - "IPC$", NULL, smb_creds, - lp_resolve_context(tctx->lp_ctx), + "IPC$", NULL, lp_socket_options(tctx->lp_ctx), + smb_creds, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, - lp_iconv_convenience(tctx->lp_ctx)); + lp_iconv_convenience(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { d_printf("smbcli_full_connection failed: %s\n", nt_errstr(status)); @@ -1717,10 +1743,11 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) status = smbcli_full_connection( mem_ctx, &cli, torture_setting_string(torture, "host", NULL), lp_smb_ports(torture->lp_ctx), - "IPC$", NULL, cmdline_credentials, + "IPC$", NULL, lp_socket_options(torture->lp_ctx), cmdline_credentials, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) smbcli_full_connection failed: %s\n", __location__, nt_errstr(status)); @@ -1744,11 +1771,12 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) status = smbcli_full_connection( mem_ctx, &cli, torture_setting_string(torture, "host", NULL), - lp_smb_ports(torture->lp_ctx), - "IPC$", NULL, anon_creds, + lp_smb_ports(torture->lp_ctx), "IPC$", NULL, + lp_socket_options(torture->lp_ctx), anon_creds, lp_resolve_context(torture->lp_ctx), torture->ev, &options, &session_options, - lp_iconv_convenience(torture->lp_ctx)); + lp_iconv_convenience(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { d_printf("(%s) anon smbcli_full_connection failed: %s\n", __location__, nt_errstr(status)); @@ -1812,6 +1840,7 @@ bool torture_samba3_rpc_getusername(struct torture_context *torture) setup.in.capabilities = cli->transport->negotiate.capabilities; setup.in.workgroup = ""; setup.in.credentials = user_creds; + setup.in.gensec_settings = lp_gensec_settings(torture, torture->lp_ctx); status = smb_composite_sesssetup(session2, &setup); if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/torture/rpc/samlogon.c b/source4/torture/rpc/samlogon.c index 9a707605e6..db4657e835 100644 --- a/source4/torture/rpc/samlogon.c +++ b/source4/torture/rpc/samlogon.c @@ -1567,7 +1567,7 @@ bool torture_rpc_samlogon(struct torture_context *torture) old_user_password = user_password; - test_ChangePasswordUser3(torture_join_samr_pipe(user_ctx), mem_ctx, + test_ChangePasswordUser3(torture_join_samr_pipe(user_ctx), torture, TEST_USER_NAME, 16 /* > 14 */, &user_password, NULL, 0, false); diff --git a/source4/torture/rpc/samr.c b/source4/torture/rpc/samr.c index 3d4c993e7b..87690178a7 100644 --- a/source4/torture/rpc/samr.c +++ b/source4/torture/rpc/samr.c @@ -59,6 +59,13 @@ static void init_lsa_String(struct lsa_String *string, const char *s) string->string = s; } +static void init_lsa_BinaryString(struct lsa_BinaryString *string, const char *s, uint32_t length) +{ + string->length = length; + string->size = length; + string->array = (uint16_t *)discard_const(s); +} + bool test_samr_handle_Close(struct dcerpc_pipe *p, struct torture_context *tctx, struct policy_handle *handle) { @@ -131,18 +138,20 @@ static bool test_QuerySecurity(struct dcerpc_pipe *p, NTSTATUS status; struct samr_QuerySecurity r; struct samr_SetSecurity s; + struct sec_desc_buf *sdbuf = NULL; r.in.handle = handle; r.in.sec_info = 7; + r.out.sdbuf = &sdbuf; status = dcerpc_samr_QuerySecurity(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "QuerySecurity"); - torture_assert(tctx, r.out.sdbuf != NULL, "sdbuf is NULL"); + torture_assert(tctx, sdbuf != NULL, "sdbuf is NULL"); s.in.handle = handle; s.in.sec_info = 7; - s.in.sdbuf = r.out.sdbuf; + s.in.sdbuf = sdbuf; if (torture_setting_bool(tctx, "samba4", false)) { torture_skip(tctx, "skipping SetSecurity test against Samba4\n"); @@ -168,6 +177,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx struct samr_QueryUserInfo q; struct samr_QueryUserInfo q0; union samr_UserInfo u; + union samr_UserInfo *info; bool ret = true; const char *test_account_name; @@ -184,7 +194,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx s2.in.info = &u; q.in.user_handle = handle; - q.out.info = &u; + q.out.info = &info; q0 = q; #define TESTCALL(call, r) \ @@ -204,6 +214,14 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx break; \ } +#define MEM_EQUAL(s1, s2, length, field) \ + if ((s1 && !s2) || (s2 && !s1) || memcmp(s1, s2, length)) { \ + torture_comment(tctx, "Failed to set %s to '%s' (%s)\n", \ + #field, (const char *)s2, __location__); \ + ret = false; \ + break; \ + } + #define INT_EQUAL(i1, i2, field) \ if (i1 != i2) { \ torture_comment(tctx, "Failed to set %s to 0x%llx - got 0x%llx (%s)\n", \ @@ -218,7 +236,7 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TESTCALL(QueryUserInfo, q) \ s.in.level = lvl1; \ s2.in.level = lvl1; \ - u = *q.out.info; \ + u = *info; \ if (lvl1 == 21) { \ ZERO_STRUCT(u.info21); \ u.info21.fields_present = fpval; \ @@ -228,21 +246,45 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TESTCALL(SetUserInfo2, s2) \ init_lsa_String(&u.info ## lvl1.field1, ""); \ TESTCALL(QueryUserInfo, q); \ - u = *q.out.info; \ + u = *info; \ STRING_EQUAL(u.info ## lvl1.field1.string, value, field1); \ q.in.level = lvl2; \ TESTCALL(QueryUserInfo, q) \ - u = *q.out.info; \ + u = *info; \ STRING_EQUAL(u.info ## lvl2.field2.string, value, field2); \ } while (0) +#define TEST_USERINFO_BINARYSTRING(lvl1, field1, lvl2, field2, value, fpval) do { \ + torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \ + q.in.level = lvl1; \ + TESTCALL(QueryUserInfo, q) \ + s.in.level = lvl1; \ + s2.in.level = lvl1; \ + u = *info; \ + if (lvl1 == 21) { \ + ZERO_STRUCT(u.info21); \ + u.info21.fields_present = fpval; \ + } \ + init_lsa_BinaryString(&u.info ## lvl1.field1, value, strlen(value)); \ + TESTCALL(SetUserInfo, s) \ + TESTCALL(SetUserInfo2, s2) \ + init_lsa_BinaryString(&u.info ## lvl1.field1, "", 1); \ + TESTCALL(QueryUserInfo, q); \ + u = *info; \ + MEM_EQUAL(u.info ## lvl1.field1.array, value, strlen(value), field1); \ + q.in.level = lvl2; \ + TESTCALL(QueryUserInfo, q) \ + u = *info; \ + MEM_EQUAL(u.info ## lvl2.field2.array, value, strlen(value), field2); \ + } while (0) + #define TEST_USERINFO_INT_EXP(lvl1, field1, lvl2, field2, value, exp_value, fpval) do { \ torture_comment(tctx, "field test %d/%s vs %d/%s\n", lvl1, #field1, lvl2, #field2); \ q.in.level = lvl1; \ TESTCALL(QueryUserInfo, q) \ s.in.level = lvl1; \ s2.in.level = lvl1; \ - u = *q.out.info; \ + u = *info; \ if (lvl1 == 21) { \ uint8_t *bits = u.info21.logon_hours.bits; \ ZERO_STRUCT(u.info21); \ @@ -257,11 +299,11 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TESTCALL(SetUserInfo2, s2) \ u.info ## lvl1.field1 = 0; \ TESTCALL(QueryUserInfo, q); \ - u = *q.out.info; \ + u = *info; \ INT_EQUAL(u.info ## lvl1.field1, exp_value, field1); \ q.in.level = lvl2; \ TESTCALL(QueryUserInfo, q) \ - u = *q.out.info; \ + u = *info; \ INT_EQUAL(u.info ## lvl2.field2, exp_value, field1); \ } while (0) @@ -359,10 +401,10 @@ static bool test_SetUserInfo(struct dcerpc_pipe *p, struct torture_context *tctx TEST_USERINFO_STRING(21, workstations, 14, workstations, "21workstation14", SAMR_FIELD_WORKSTATIONS); - TEST_USERINFO_STRING(20, parameters, 21, parameters, "xx20-21 parameters", 0); - TEST_USERINFO_STRING(21, parameters, 21, parameters, "xx21-21 parameters", + TEST_USERINFO_BINARYSTRING(20, parameters, 21, parameters, "xx20-21 parameters", 0); + TEST_USERINFO_BINARYSTRING(21, parameters, 21, parameters, "xx21-21 parameters", SAMR_FIELD_PARAMETERS); - TEST_USERINFO_STRING(21, parameters, 20, parameters, "xx21-20 parameters", + TEST_USERINFO_BINARYSTRING(21, parameters, 20, parameters, "xx21-20 parameters", SAMR_FIELD_PARAMETERS); TEST_USERINFO_INT(2, country_code, 2, country_code, __LINE__, 0); @@ -512,12 +554,14 @@ static bool test_SetUserPass(struct dcerpc_pipe *p, struct torture_context *tctx DATA_BLOB session_key; char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -564,12 +608,14 @@ static bool test_SetUserPass_23(struct dcerpc_pipe *p, struct torture_context *t DATA_BLOB session_key; char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -643,12 +689,14 @@ static bool test_SetUserPassEx(struct dcerpc_pipe *p, struct torture_context *tc char *newpass; struct MD5Context ctx; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } if (makeshort && policy_min_pw_len) { newpass = samr_rand_pass_fixed_len(tctx, policy_min_pw_len - 1); @@ -725,12 +773,14 @@ static bool test_SetUserPass_25(struct dcerpc_pipe *p, struct torture_context *t uint8_t confounder[16]; char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; pwp.in.user_handle = handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -796,6 +846,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct NTSTATUS status; struct samr_SetAliasInfo r; struct samr_QueryAliasInfo q; + union samr_AliasInfo *info; uint16_t levels[] = {2, 3}; int i; bool ret = true; @@ -826,6 +877,7 @@ static bool test_SetAliasInfo(struct dcerpc_pipe *p, struct torture_context *tct q.in.alias_handle = handle; q.in.level = levels[i]; + q.out.info = &info; status = dcerpc_samr_QueryAliasInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -842,11 +894,13 @@ static bool test_GetGroupsForUser(struct dcerpc_pipe *p, struct torture_context struct policy_handle *user_handle) { struct samr_GetGroupsForUser r; + struct samr_RidWithAttributeArray *rids = NULL; NTSTATUS status; torture_comment(tctx, "testing GetGroupsForUser\n"); r.in.user_handle = user_handle; + r.out.rids = &rids; status = dcerpc_samr_GetGroupsForUser(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetGroupsForUser"); @@ -860,8 +914,11 @@ static bool test_GetDomPwInfo(struct dcerpc_pipe *p, struct torture_context *tct { NTSTATUS status; struct samr_GetDomPwInfo r; + struct samr_PwInfo info; r.in.domain_name = domain_name; + r.out.info = &info; + torture_comment(tctx, "Testing GetDomPwInfo with name %s\n", r.in.domain_name->string); status = dcerpc_samr_GetDomPwInfo(p, tctx, &r); @@ -893,10 +950,12 @@ static bool test_GetUserPwInfo(struct dcerpc_pipe *p, struct torture_context *tc { NTSTATUS status; struct samr_GetUserPwInfo r; + struct samr_PwInfo info; torture_comment(tctx, "Testing GetUserPwInfo\n"); r.in.user_handle = handle; + r.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "GetUserPwInfo"); @@ -911,15 +970,18 @@ static NTSTATUS test_LookupName(struct dcerpc_pipe *p, struct torture_context *t NTSTATUS status; struct samr_LookupNames n; struct lsa_String sname[2]; + struct samr_Ids rids, types; init_lsa_String(&sname[0], name); n.in.domain_handle = domain_handle; n.in.num_names = 1; n.in.names = sname; + n.out.rids = &rids; + n.out.types = &types; status = dcerpc_samr_LookupNames(p, tctx, &n); if (NT_STATUS_IS_OK(status)) { - *rid = n.out.rids.ids[0]; + *rid = n.out.rids->ids[0]; } else { return status; } @@ -1071,6 +1133,7 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex char *newpass; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; int policy_min_pw_len = 0; status = test_OpenUser_byname(p, tctx, handle, acct_name, &user_handle); @@ -1078,10 +1141,11 @@ static bool test_ChangePasswordUser(struct dcerpc_pipe *p, struct torture_contex return false; } pwp.in.user_handle = &user_handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(p, tctx, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -1346,12 +1410,14 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co uint8_t old_lm_hash[16], new_lm_hash[16]; struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; int policy_min_pw_len = 0; struct lsa_String domain_name; domain_name.string = ""; dom_pw_info.in.domain_name = &domain_name; + dom_pw_info.out.info = &info; torture_comment(tctx, "Testing OemChangePasswordUser2\n"); @@ -1362,7 +1428,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = dom_pw_info.out.info.min_password_length; + policy_min_pw_len = dom_pw_info.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -1389,7 +1455,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { - printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n", + printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalid password verifier - %s\n", nt_errstr(status)); ret = false; } @@ -1411,7 +1477,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && !NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { - printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n", + printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD (or at least 'PASSWORD_RESTRICTON') for invalidly encrpted password - %s\n", nt_errstr(status)); ret = false; } @@ -1428,7 +1494,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && !NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n", + printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER (or at least 'PASSWORD_RESTRICTON') for no supplied validation hash - %s\n", nt_errstr(status)); ret = false; } @@ -1440,7 +1506,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n", + printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied validation hash and invalid user - %s\n", nt_errstr(status)); ret = false; } @@ -1454,7 +1520,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_WRONG_PASSWORD)) { - printf("ChangePasswordUser3 failed, should have returned WRONG_PASSWORD for invalid user - %s\n", + printf("OemChangePasswordUser2 failed, should have returned WRONG_PASSWORD for invalid user - %s\n", nt_errstr(status)); ret = false; } @@ -1468,7 +1534,7 @@ static bool test_OemChangePasswordUser2(struct dcerpc_pipe *p, struct torture_co status = dcerpc_samr_OemChangePasswordUser2(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER)) { - printf("ChangePasswordUser3 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n", + printf("OemChangePasswordUser2 failed, should have returned INVALID_PARAMETER for no supplied password and invalid user - %s\n", nt_errstr(status)); ret = false; } @@ -1515,23 +1581,25 @@ static bool test_ChangePasswordUser2(struct dcerpc_pipe *p, struct torture_conte uint8_t old_lm_hash[16], new_lm_hash[16]; struct samr_GetDomPwInfo dom_pw_info; + struct samr_PwInfo info; struct lsa_String domain_name; domain_name.string = ""; dom_pw_info.in.domain_name = &domain_name; + dom_pw_info.out.info = &info; torture_comment(tctx, "Testing ChangePasswordUser2 on %s\n", acct_name); torture_assert(tctx, *password != NULL, - "Failing ChangePasswordUser3 as old password was NULL. Previous test failed?"); + "Failing ChangePasswordUser2 as old password was NULL. Previous test failed?"); oldpass = *password; if (!newpass) { int policy_min_pw_len = 0; status = dcerpc_samr_GetDomPwInfo(p, tctx, &dom_pw_info); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = dom_pw_info.out.info.min_password_length; + policy_min_pw_len = dom_pw_info.out.info->min_password_length; } newpass = samr_rand_pass(tctx, policy_min_pw_len); @@ -1594,6 +1662,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct uint8_t old_nt_hash[16], new_nt_hash[16]; uint8_t old_lm_hash[16], new_lm_hash[16]; NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct samr_ChangeReject *reject = NULL; torture_comment(tctx, "Testing ChangePasswordUser3\n"); @@ -1641,6 +1711,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && @@ -1670,6 +1742,8 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (!NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) && @@ -1712,21 +1786,23 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct r.in.lm_password = &lm_pass; r.in.lm_verifier = &lm_verifier; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION) - && r.out.dominfo - && r.out.reject + && dominfo + && reject && handle_reject_reason - && (!null_nttime(last_password_change) || !r.out.dominfo->min_password_age)) { - if (r.out.dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) { + && (!null_nttime(last_password_change) || !dominfo->min_password_age)) { + if (dominfo->password_properties & DOMAIN_REFUSE_PASSWORD_CHANGE ) { - if (r.out.reject && (r.out.reject->reason != SAMR_REJECT_OTHER)) { + if (reject && (reject->reason != SAMR_REJECT_OTHER)) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } } @@ -1740,54 +1816,54 @@ bool test_ChangePasswordUser3(struct dcerpc_pipe *p, struct torture_context *tct Guenther */ - if ((r.out.dominfo->min_password_age > 0) && !null_nttime(last_password_change) && - (last_password_change + r.out.dominfo->min_password_age > t)) { + if ((dominfo->min_password_age > 0) && !null_nttime(last_password_change) && + (last_password_change + dominfo->min_password_age > t)) { - if (r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } - } else if ((r.out.dominfo->min_password_length > 0) && - (strlen(newpass) < r.out.dominfo->min_password_length)) { + } else if ((dominfo->min_password_length > 0) && + (strlen(newpass) < dominfo->min_password_length)) { - if (r.out.reject->reason != SAMR_REJECT_TOO_SHORT) { + if (reject->reason != SAMR_REJECT_TOO_SHORT) { printf("expected SAMR_REJECT_TOO_SHORT (%d), got %d\n", - SAMR_REJECT_TOO_SHORT, r.out.reject->reason); + SAMR_REJECT_TOO_SHORT, reject->reason); return false; } - } else if ((r.out.dominfo->password_history_length > 0) && + } else if ((dominfo->password_history_length > 0) && strequal(oldpass, newpass)) { - if (r.out.reject->reason != SAMR_REJECT_IN_HISTORY) { + if (reject->reason != SAMR_REJECT_IN_HISTORY) { printf("expected SAMR_REJECT_IN_HISTORY (%d), got %d\n", - SAMR_REJECT_IN_HISTORY, r.out.reject->reason); + SAMR_REJECT_IN_HISTORY, reject->reason); return false; } - } else if (r.out.dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) { + } else if (dominfo->password_properties & DOMAIN_PASSWORD_COMPLEX) { - if (r.out.reject->reason != SAMR_REJECT_COMPLEXITY) { + if (reject->reason != SAMR_REJECT_COMPLEXITY) { printf("expected SAMR_REJECT_COMPLEXITY (%d), got %d\n", - SAMR_REJECT_COMPLEXITY, r.out.reject->reason); + SAMR_REJECT_COMPLEXITY, reject->reason); return false; } } - if (r.out.reject->reason == SAMR_REJECT_TOO_SHORT) { + if (reject->reason == SAMR_REJECT_TOO_SHORT) { /* retry with adjusted size */ return test_ChangePasswordUser3(p, tctx, account_string, - r.out.dominfo->min_password_length, + dominfo->min_password_length, password, NULL, 0, false); } } else if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { - if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject && reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ @@ -1823,6 +1899,8 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex char *oldpass; uint8_t old_nt_hash[16], new_nt_hash[16]; NTTIME t; + struct samr_DomInfo1 *dominfo = NULL; + struct samr_ChangeReject *reject = NULL; new_random_pass = samr_very_rand_pass(tctx, 128); @@ -1889,15 +1967,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex r.in.lm_password = NULL; r.in.lm_verifier = NULL; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { - if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject && reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ @@ -1925,15 +2005,17 @@ bool test_ChangePasswordRandomBytes(struct dcerpc_pipe *p, struct torture_contex r.in.lm_password = NULL; r.in.lm_verifier = NULL; r.in.password3 = NULL; + r.out.dominfo = &dominfo; + r.out.reject = &reject; unix_to_nt_time(&t, time(NULL)); status = dcerpc_samr_ChangePasswordUser3(p, tctx, &r); if (NT_STATUS_EQUAL(status, NT_STATUS_PASSWORD_RESTRICTION)) { - if (r.out.reject && r.out.reject->reason != SAMR_REJECT_OTHER) { + if (reject && reject->reason != SAMR_REJECT_OTHER) { printf("expected SAMR_REJECT_OTHER (%d), got %d\n", - SAMR_REJECT_OTHER, r.out.reject->reason); + SAMR_REJECT_OTHER, reject->reason); return false; } /* Perhaps the server has a 'min password age' set? */ @@ -2061,6 +2143,7 @@ static bool test_user_ops(struct dcerpc_pipe *p, { char *password = NULL; struct samr_QueryUserInfo q; + union samr_UserInfo *info; NTSTATUS status; bool ret = true; @@ -2176,6 +2259,7 @@ static bool test_user_ops(struct dcerpc_pipe *p, q.in.user_handle = user_handle; q.in.level = 5; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2184,15 +2268,15 @@ static bool test_user_ops(struct dcerpc_pipe *p, ret = false; } else { uint32_t expected_flags = (base_acct_flags | ACB_PWNOTREQ | ACB_DISABLED); - if ((q.out.info->info5.acct_flags) != expected_flags) { + if ((info->info5.acct_flags) != expected_flags) { printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n", - q.out.info->info5.acct_flags, + info->info5.acct_flags, expected_flags); ret = false; } - if (q.out.info->info5.rid != rid) { + if (info->info5.rid != rid) { printf("QuerUserInfo level 5 failed, it returned %u when we expected rid of %u\n", - q.out.info->info5.rid, rid); + info->info5.rid, rid); } } @@ -2481,6 +2565,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, /* set samr_SetDomainInfo level 1 with min_length 5 */ { struct samr_QueryDomainInfo r; + union samr_DomainInfo *info = NULL; struct samr_SetDomainInfo s; uint16_t len_old, len; uint32_t pwd_prop_old; @@ -2491,6 +2576,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.domain_handle = domain_handle; r.in.level = 1; + r.out.info = &info; printf("testing samr_QueryDomainInfo level 1\n"); status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &r); @@ -2500,7 +2586,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, s.in.domain_handle = domain_handle; s.in.level = 1; - s.in.info = r.out.info; + s.in.info = info; /* remember the old min length, so we can reset it */ len_old = s.in.info->info1.min_password_length; @@ -2540,13 +2626,17 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct samr_LookupNames n; struct policy_handle user_handle; + struct samr_Ids rids, types; n.in.domain_handle = domain_handle; n.in.num_names = 1; n.in.names = talloc_array(mem_ctx, struct lsa_String, 1); n.in.names[0].string = acct_name; + n.out.rids = &rids; + n.out.types = &types; status = dcerpc_samr_LookupNames(p, mem_ctx, &n); if (!NT_STATUS_IS_OK(status)) { @@ -2556,17 +2646,18 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.domain_handle = domain_handle; r.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r.in.rid = n.out.rids.ids[0]; + r.in.rid = n.out.rids->ids[0]; r.out.user_handle = &user_handle; status = dcerpc_samr_OpenUser(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { - printf("OpenUser(%u) failed - %s\n", n.out.rids.ids[0], nt_errstr(status)); + printf("OpenUser(%u) failed - %s\n", n.out.rids->ids[0], nt_errstr(status)); return false; } q.in.user_handle = &user_handle; q.in.level = 5; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2577,7 +2668,7 @@ static bool test_ChangePassword(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, printf("calling test_ChangePasswordUser3 with too early password change\n"); if (!test_ChangePasswordUser3(p, mem_ctx, acct_name, 0, password, NULL, - q.out.info->info5.last_password_change, true)) { + info->info5.last_password_change, true)) { ret = false; } } @@ -2607,6 +2698,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, NTSTATUS status; struct samr_CreateUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct samr_DeleteUser d; uint32_t rid; @@ -2654,6 +2746,7 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, } else { q.in.user_handle = &user_handle; q.in.level = 16; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2661,9 +2754,9 @@ static bool test_CreateUser(struct dcerpc_pipe *p, struct torture_context *tctx, q.in.level, nt_errstr(status)); ret = false; } else { - if ((q.out.info->info16.acct_flags & acct_flags) != acct_flags) { + if ((info->info16.acct_flags & acct_flags) != acct_flags) { printf("QuerUserInfo level 16 failed, it returned 0x%08x when we expected flags of 0x%08x\n", - q.out.info->info16.acct_flags, + info->info16.acct_flags, acct_flags); ret = false; } @@ -2705,6 +2798,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx NTSTATUS status; struct samr_CreateUser2 r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct samr_DeleteUser d; struct policy_handle user_handle; uint32_t rid; @@ -2783,6 +2877,7 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx if (NT_STATUS_IS_OK(status)) { q.in.user_handle = &user_handle; q.in.level = 5; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, user_ctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -2794,31 +2889,31 @@ static bool test_CreateUser2(struct dcerpc_pipe *p, struct torture_context *tctx if (acct_flags == ACB_NORMAL) { expected_flags |= ACB_PW_EXPIRED; } - if ((q.out.info->info5.acct_flags) != expected_flags) { + if ((info->info5.acct_flags) != expected_flags) { printf("QuerUserInfo level 5 failed, it returned 0x%08x when we expected flags of 0x%08x\n", - q.out.info->info5.acct_flags, + info->info5.acct_flags, expected_flags); ret = false; } switch (acct_flags) { case ACB_SVRTRUST: - if (q.out.info->info5.primary_gid != DOMAIN_RID_DCS) { + if (info->info5.primary_gid != DOMAIN_RID_DCS) { printf("QuerUserInfo level 5: DC should have had Primary Group %d, got %d\n", - DOMAIN_RID_DCS, q.out.info->info5.primary_gid); + DOMAIN_RID_DCS, info->info5.primary_gid); ret = false; } break; case ACB_WSTRUST: - if (q.out.info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) { + if (info->info5.primary_gid != DOMAIN_RID_DOMAIN_MEMBERS) { printf("QuerUserInfo level 5: Domain Member should have had Primary Group %d, got %d\n", - DOMAIN_RID_DOMAIN_MEMBERS, q.out.info->info5.primary_gid); + DOMAIN_RID_DOMAIN_MEMBERS, info->info5.primary_gid); ret = false; } break; case ACB_NORMAL: - if (q.out.info->info5.primary_gid != DOMAIN_RID_USERS) { + if (info->info5.primary_gid != DOMAIN_RID_USERS) { printf("QuerUserInfo level 5: Users should have had Primary Group %d, got %d\n", - DOMAIN_RID_USERS, q.out.info->info5.primary_gid); + DOMAIN_RID_USERS, info->info5.primary_gid); ret = false; } break; @@ -2852,6 +2947,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryAliasInfo r; + union samr_AliasInfo *info; uint16_t levels[] = {1, 2, 3}; int i; bool ret = true; @@ -2861,6 +2957,7 @@ static bool test_QueryAliasInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.alias_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryAliasInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2878,6 +2975,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryGroupInfo r; + union samr_GroupInfo *info; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; bool ret = true; @@ -2887,6 +2985,7 @@ static bool test_QueryGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.group_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2904,11 +3003,13 @@ static bool test_QueryGroupMember(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryGroupMember r; + struct samr_RidTypeArray *rids = NULL; bool ret = true; printf("Testing QueryGroupMember\n"); r.in.group_handle = handle; + r.out.rids = &rids; status = dcerpc_samr_QueryGroupMember(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2925,6 +3026,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryGroupInfo r; + union samr_GroupInfo *info; struct samr_SetGroupInfo s; uint16_t levels[] = {1, 2, 3, 4}; uint16_t set_ok[] = {0, 1, 1, 1}; @@ -2936,6 +3038,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.group_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryGroupInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -2948,7 +3051,7 @@ static bool test_SetGroupInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, s.in.group_handle = handle; s.in.level = levels[i]; - s.in.info = r.out.info; + s.in.info = *r.out.info; #if 0 /* disabled this, as it changes the name only from the point of view of samr, @@ -2990,6 +3093,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryUserInfo r; + union samr_UserInfo *info; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20, 21}; int i; @@ -3000,6 +3104,7 @@ static bool test_QueryUserInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.user_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3017,6 +3122,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, { NTSTATUS status; struct samr_QueryUserInfo2 r; + union samr_UserInfo *info; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 20, 21}; int i; @@ -3027,6 +3133,7 @@ static bool test_QueryUserInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.user_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryUserInfo2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3174,6 +3281,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, NTSTATUS status; struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct policy_handle user_handle; bool ret = true; @@ -3192,6 +3300,7 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, q.in.user_handle = &user_handle; q.in.level = 16; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, tctx, &q); if (!NT_STATUS_IS_OK(status)) { @@ -3199,9 +3308,9 @@ static bool check_mask(struct dcerpc_pipe *p, struct torture_context *tctx, nt_errstr(status)); ret = false; } else { - if ((acct_flag_mask & q.out.info->info16.acct_flags) == 0) { + if ((acct_flag_mask & info->info16.acct_flags) == 0) { printf("Server failed to filter for 0x%x, allowed 0x%x (%d) on EnumDomainUsers\n", - acct_flag_mask, q.out.info->info16.acct_flags, rid); + acct_flag_mask, info->info16.acct_flags, rid); ret = false; } } @@ -3223,6 +3332,11 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * bool ret = true; struct samr_LookupNames n; struct samr_LookupRids lr ; + struct lsa_Strings names; + struct samr_Ids rids, types; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; + uint32_t masks[] = {ACB_NORMAL, ACB_DOMTRUST, ACB_WSTRUST, ACB_DISABLED, ACB_NORMAL | ACB_DISABLED, ACB_SVRTRUST | ACB_DOMTRUST | ACB_WSTRUST, @@ -3236,6 +3350,8 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * r.in.acct_flags = mask = masks[mask_idx]; r.in.max_size = (uint32_t)-1; r.out.resume_handle = &resume_handle; + r.out.num_entries = &num_entries; + r.out.sam = &sam; status = dcerpc_samr_EnumDomainUsers(p, tctx, &r); if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && @@ -3244,18 +3360,18 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * return false; } - torture_assert(tctx, r.out.sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL"); + torture_assert(tctx, sam, "EnumDomainUsers failed: r.out.sam unexpectedly NULL"); - if (r.out.sam->count == 0) { + if (sam->count == 0) { continue; } - for (i=0;i<r.out.sam->count;i++) { + for (i=0;i<sam->count;i++) { if (mask) { - if (!check_mask(p, tctx, handle, r.out.sam->entries[i].idx, mask)) { + if (!check_mask(p, tctx, handle, sam->entries[i].idx, mask)) { ret = false; } - } else if (!test_OpenUser(p, tctx, handle, r.out.sam->entries[i].idx)) { + } else if (!test_OpenUser(p, tctx, handle, sam->entries[i].idx)) { ret = false; } } @@ -3263,10 +3379,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * printf("Testing LookupNames\n"); n.in.domain_handle = handle; - n.in.num_names = r.out.sam->count; - n.in.names = talloc_array(tctx, struct lsa_String, r.out.sam->count); - for (i=0;i<r.out.sam->count;i++) { - n.in.names[i].string = r.out.sam->entries[i].name.string; + n.in.num_names = sam->count; + n.in.names = talloc_array(tctx, struct lsa_String, sam->count); + n.out.rids = &rids; + n.out.types = &types; + for (i=0;i<sam->count;i++) { + n.in.names[i].string = sam->entries[i].name.string; } status = dcerpc_samr_LookupNames(p, tctx, &n); if (!NT_STATUS_IS_OK(status)) { @@ -3277,10 +3395,12 @@ static bool test_EnumDomainUsers(struct dcerpc_pipe *p, struct torture_context * printf("Testing LookupRids\n"); lr.in.domain_handle = handle; - lr.in.num_rids = r.out.sam->count; - lr.in.rids = talloc_array(tctx, uint32_t, r.out.sam->count); - for (i=0;i<r.out.sam->count;i++) { - lr.in.rids[i] = r.out.sam->entries[i].idx; + lr.in.num_rids = sam->count; + lr.in.rids = talloc_array(tctx, uint32_t, sam->count); + lr.out.names = &names; + lr.out.types = &types; + for (i=0;i<sam->count;i++) { + lr.in.rids[i] = sam->entries[i].idx; } status = dcerpc_samr_LookupRids(p, tctx, &lr); torture_assert_ntstatus_ok(tctx, status, "LookupRids"); @@ -3337,6 +3457,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_EnumDomainGroups r; uint32_t resume_handle=0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; int i; bool ret = true; @@ -3346,6 +3468,8 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.resume_handle = &resume_handle; r.in.max_size = (uint32_t)-1; r.out.resume_handle = &resume_handle; + r.out.num_entries = &num_entries; + r.out.sam = &sam; status = dcerpc_samr_EnumDomainGroups(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3353,12 +3477,12 @@ static bool test_EnumDomainGroups(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - if (!r.out.sam) { + if (!sam) { return false; } - for (i=0;i<r.out.sam->count;i++) { - if (!test_OpenGroup(p, mem_ctx, handle, r.out.sam->entries[i].idx)) { + for (i=0;i<sam->count;i++) { + if (!test_OpenGroup(p, mem_ctx, handle, sam->entries[i].idx)) { ret = false; } } @@ -3372,6 +3496,8 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_EnumDomainAliases r; uint32_t resume_handle=0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; int i; bool ret = true; @@ -3379,7 +3505,9 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.domain_handle = handle; r.in.resume_handle = &resume_handle; - r.in.acct_flags = (uint32_t)-1; + r.in.max_size = (uint32_t)-1; + r.out.sam = &sam; + r.out.num_entries = &num_entries; r.out.resume_handle = &resume_handle; status = dcerpc_samr_EnumDomainAliases(p, mem_ctx, &r); @@ -3388,12 +3516,12 @@ static bool test_EnumDomainAliases(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, return false; } - if (!r.out.sam) { + if (!sam) { return false; } - for (i=0;i<r.out.sam->count;i++) { - if (!test_OpenAlias(p, mem_ctx, handle, r.out.sam->entries[i].idx)) { + for (i=0;i<sam->count;i++) { + if (!test_OpenAlias(p, mem_ctx, handle, sam->entries[i].idx)) { ret = false; } } @@ -3409,14 +3537,19 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; uint16_t ok_lvl[] = {1, 1, 1, 0, 0}; + struct lsa_String name; + uint32_t idx = 0; int i; for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing GetDisplayEnumerationIndex level %u\n", levels[i]); + init_lsa_String(&name, TEST_ACCOUNT_NAME); + r.in.domain_handle = handle; r.in.level = levels[i]; - init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME); + r.in.name = &name; + r.out.idx = &idx; status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r); @@ -3428,7 +3561,7 @@ static bool test_GetDisplayEnumerationIndex(struct dcerpc_pipe *p, TALLOC_CTX *m ret = false; } - init_lsa_String(&r.in.name, "zzzzzzzz"); + init_lsa_String(&name, "zzzzzzzz"); status = dcerpc_samr_GetDisplayEnumerationIndex(p, mem_ctx, &r); @@ -3450,14 +3583,19 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX * bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; uint16_t ok_lvl[] = {1, 1, 1, 0, 0}; + struct lsa_String name; + uint32_t idx = 0; int i; for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing GetDisplayEnumerationIndex2 level %u\n", levels[i]); + init_lsa_String(&name, TEST_ACCOUNT_NAME); + r.in.domain_handle = handle; r.in.level = levels[i]; - init_lsa_String(&r.in.name, TEST_ACCOUNT_NAME); + r.in.name = &name; + r.out.idx = &idx; status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r); if (ok_lvl[i] && @@ -3468,7 +3606,7 @@ static bool test_GetDisplayEnumerationIndex2(struct dcerpc_pipe *p, TALLOC_CTX * ret = false; } - init_lsa_String(&r.in.name, "zzzzzzzz"); + init_lsa_String(&name, "zzzzzzzz"); status = dcerpc_samr_GetDisplayEnumerationIndex2(p, mem_ctx, &r); if (ok_lvl[i] && !NT_STATUS_EQUAL(NT_STATUS_NO_MORE_ENTRIES, status)) { @@ -3502,6 +3640,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct { struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct policy_handle user_handle; int i, ret = true; NTSTATUS status; @@ -3510,16 +3649,16 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct for (i = 0; ; i++) { switch (querydisplayinfo->in.level) { case 1: - if (i >= querydisplayinfo->out.info.info1.count) { + if (i >= querydisplayinfo->out.info->info1.count) { return ret; } - r.in.rid = querydisplayinfo->out.info.info1.entries[i].rid; + r.in.rid = querydisplayinfo->out.info->info1.entries[i].rid; break; case 2: - if (i >= querydisplayinfo->out.info.info2.count) { + if (i >= querydisplayinfo->out.info->info2.count) { return ret; } - r.in.rid = querydisplayinfo->out.info.info2.entries[i].rid; + r.in.rid = querydisplayinfo->out.info->info2.entries[i].rid; break; case 3: /* Groups */ @@ -3543,6 +3682,7 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct q.in.user_handle = &user_handle; q.in.level = 21; + q.out.info = &info; status = dcerpc_samr_QueryUserInfo(p, mem_ctx, &q); if (!NT_STATUS_IS_OK(status)) { printf("QueryUserInfo(%u) failed - %s\n", r.in.rid, nt_errstr(status)); @@ -3551,41 +3691,41 @@ static bool test_each_DisplayInfo_user(struct dcerpc_pipe *p, TALLOC_CTX *mem_ct switch (querydisplayinfo->in.level) { case 1: - if (seen_testuser && strcmp(q.out.info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) { + if (seen_testuser && strcmp(info->info21.account_name.string, TEST_ACCOUNT_NAME) == 0) { *seen_testuser = true; } - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].full_name, - q.out.info->info21.full_name, q.out.info->info21.account_name); - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].account_name, - q.out.info->info21.account_name, q.out.info->info21.account_name); - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].description, - q.out.info->info21.description, q.out.info->info21.account_name); - INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].rid, - q.out.info->info21.rid, q.out.info->info21.account_name); - INT_EQUAL_QUERY(querydisplayinfo->out.info.info1.entries[i].acct_flags, - q.out.info->info21.acct_flags, q.out.info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].full_name, + info->info21.full_name, info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].account_name, + info->info21.account_name, info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].description, + info->info21.description, info->info21.account_name); + INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].rid, + info->info21.rid, info->info21.account_name); + INT_EQUAL_QUERY(querydisplayinfo->out.info->info1.entries[i].acct_flags, + info->info21.acct_flags, info->info21.account_name); break; case 2: - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].account_name, - q.out.info->info21.account_name, q.out.info->info21.account_name); - STRING_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].description, - q.out.info->info21.description, q.out.info->info21.account_name); - INT_EQUAL_QUERY(querydisplayinfo->out.info.info2.entries[i].rid, - q.out.info->info21.rid, q.out.info->info21.account_name); - INT_EQUAL_QUERY((querydisplayinfo->out.info.info2.entries[i].acct_flags & ~ACB_NORMAL), - q.out.info->info21.acct_flags, q.out.info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].account_name, + info->info21.account_name, info->info21.account_name); + STRING_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].description, + info->info21.description, info->info21.account_name); + INT_EQUAL_QUERY(querydisplayinfo->out.info->info2.entries[i].rid, + info->info21.rid, info->info21.account_name); + INT_EQUAL_QUERY((querydisplayinfo->out.info->info2.entries[i].acct_flags & ~ACB_NORMAL), + info->info21.acct_flags, info->info21.account_name); - if (!(querydisplayinfo->out.info.info2.entries[i].acct_flags & ACB_NORMAL)) { + if (!(querydisplayinfo->out.info->info2.entries[i].acct_flags & ACB_NORMAL)) { printf("Missing ACB_NORMAL in querydisplayinfo->out.info.info2.entries[i].acct_flags on %s\n", - q.out.info->info21.account_name.string); + info->info21.account_name.string); } - if (!(q.out.info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) { + if (!(info->info21.acct_flags & (ACB_WSTRUST | ACB_SVRTRUST))) { printf("Found non-trust account %s in trust account listing: 0x%x 0x%x\n", - q.out.info->info21.account_name.string, - querydisplayinfo->out.info.info2.entries[i].acct_flags, - q.out.info->info21.acct_flags); + info->info21.account_name.string, + querydisplayinfo->out.info->info2.entries[i].acct_flags, + info->info21.acct_flags); return false; } @@ -3605,10 +3745,15 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, NTSTATUS status; struct samr_QueryDisplayInfo r; struct samr_QueryDomainInfo dom_info; + union samr_DomainInfo *info = NULL; bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; bool seen_testuser = false; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo disp_info; + for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing QueryDisplayInfo level %u\n", levels[i]); @@ -3620,6 +3765,9 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.level = levels[i]; r.in.max_entries = 2; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &disp_info; status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r); if (!NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) && !NT_STATUS_IS_OK(status)) { @@ -3632,27 +3780,29 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, if (!test_each_DisplayInfo_user(p, mem_ctx, &r, &seen_testuser)) { ret = false; } - r.in.start_idx += r.out.info.info1.count; + r.in.start_idx += r.out.info->info1.count; break; case 2: if (!test_each_DisplayInfo_user(p, mem_ctx, &r, NULL)) { ret = false; } - r.in.start_idx += r.out.info.info2.count; + r.in.start_idx += r.out.info->info2.count; break; case 3: - r.in.start_idx += r.out.info.info3.count; + r.in.start_idx += r.out.info->info3.count; break; case 4: - r.in.start_idx += r.out.info.info4.count; + r.in.start_idx += r.out.info->info4.count; break; case 5: - r.in.start_idx += r.out.info.info5.count; + r.in.start_idx += r.out.info->info5.count; break; } } dom_info.in.domain_handle = handle; dom_info.in.level = 2; + dom_info.out.info = &info; + /* Check number of users returned is correct */ status = dcerpc_samr_QueryDomainInfo(p, mem_ctx, &dom_info); if (!NT_STATUS_IS_OK(status)) { @@ -3664,17 +3814,17 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, switch (r.in.level) { case 1: case 4: - if (dom_info.out.info->general.num_users < r.in.start_idx) { + if (info->general.num_users < r.in.start_idx) { printf("QueryDomainInfo indicates that QueryDisplayInfo returned more users (%d/%d) than the domain %s is said to contain!\n", - r.in.start_idx, dom_info.out.info->general.num_groups, - dom_info.out.info->general.domain_name.string); + r.in.start_idx, info->general.num_groups, + info->general.domain_name.string); ret = false; } if (!seen_testuser) { struct policy_handle user_handle; if (NT_STATUS_IS_OK(test_OpenUser_byname(p, mem_ctx, handle, TEST_ACCOUNT_NAME, &user_handle))) { printf("Didn't find test user " TEST_ACCOUNT_NAME " in enumeration of %s\n", - dom_info.out.info->general.domain_name.string); + info->general.domain_name.string); ret = false; test_samr_handle_Close(p, mem_ctx, &user_handle); } @@ -3682,10 +3832,10 @@ static bool test_QueryDisplayInfo(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, break; case 3: case 5: - if (dom_info.out.info->general.num_groups != r.in.start_idx) { + if (info->general.num_groups != r.in.start_idx) { printf("QueryDomainInfo indicates that QueryDisplayInfo didn't return all (%d/%d) the groups in %s\n", - r.in.start_idx, dom_info.out.info->general.num_groups, - dom_info.out.info->general.domain_name.string); + r.in.start_idx, info->general.num_groups, + info->general.domain_name.string); ret = false; } @@ -3705,6 +3855,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; for (i=0;i<ARRAY_SIZE(levels);i++) { printf("Testing QueryDisplayInfo2 level %u\n", levels[i]); @@ -3714,6 +3867,9 @@ static bool test_QueryDisplayInfo2(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, r.in.start_idx = 0; r.in.max_entries = 1000; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &info; status = dcerpc_samr_QueryDisplayInfo2(p, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3734,6 +3890,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context bool ret = true; uint16_t levels[] = {1, 2, 3, 4, 5}; int i; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; for (i=0;i<ARRAY_SIZE(levels);i++) { torture_comment(tctx, "Testing QueryDisplayInfo3 level %u\n", levels[i]); @@ -3743,6 +3902,9 @@ static bool test_QueryDisplayInfo3(struct dcerpc_pipe *p, struct torture_context r.in.start_idx = 0; r.in.max_entries = 1000; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &info; status = dcerpc_samr_QueryDisplayInfo3(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3762,6 +3924,9 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me NTSTATUS status; struct samr_QueryDisplayInfo r; bool ret = true; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; printf("Testing QueryDisplayInfo continuation\n"); @@ -3770,14 +3935,17 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me r.in.start_idx = 0; r.in.max_entries = 1; r.in.buf_size = (uint32_t)-1; + r.out.total_size = &total_size; + r.out.returned_size = &returned_size; + r.out.info = &info; do { status = dcerpc_samr_QueryDisplayInfo(p, mem_ctx, &r); - if (NT_STATUS_IS_OK(status) && r.out.returned_size != 0) { - if (r.out.info.info1.entries[0].idx != r.in.start_idx + 1) { + if (NT_STATUS_IS_OK(status) && *r.out.returned_size != 0) { + if (r.out.info->info1.entries[0].idx != r.in.start_idx + 1) { printf("expected idx %d but got %d\n", r.in.start_idx + 1, - r.out.info.info1.entries[0].idx); + r.out.info->info1.entries[0].idx); break; } } @@ -3791,7 +3959,7 @@ static bool test_QueryDisplayInfo_continue(struct dcerpc_pipe *p, TALLOC_CTX *me r.in.start_idx++; } while ((NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES) || NT_STATUS_IS_OK(status)) && - r.out.returned_size != 0); + *r.out.returned_size != 0); return ret; } @@ -3801,6 +3969,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * { NTSTATUS status; struct samr_QueryDomainInfo r; + union samr_DomainInfo *info = NULL; struct samr_SetDomainInfo s; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13}; uint16_t set_ok[] = {1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0}; @@ -3827,6 +3996,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * r.in.domain_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryDomainInfo(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3838,40 +4008,40 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * switch (levels[i]) { case 2: - if (strcmp(r.out.info->general.oem_information.string, domain_comment) != 0) { + if (strcmp(info->general.oem_information.string, domain_comment) != 0) { printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n", - levels[i], r.out.info->general.oem_information.string, domain_comment); + levels[i], info->general.oem_information.string, domain_comment); ret = false; } - if (!r.out.info->general.primary.string) { + if (!info->general.primary.string) { printf("QueryDomainInfo level %u returned no PDC name\n", levels[i]); ret = false; - } else if (r.out.info->general.role == SAMR_ROLE_DOMAIN_PDC) { - if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), r.out.info->general.primary.string) != 0) { + } else if (info->general.role == SAMR_ROLE_DOMAIN_PDC) { + if (dcerpc_server_name(p) && strcasecmp_m(dcerpc_server_name(p), info->general.primary.string) != 0) { printf("QueryDomainInfo level %u returned different PDC name (%s) compared to server name (%s), despite claiming to be the PDC\n", - levels[i], r.out.info->general.primary.string, dcerpc_server_name(p)); + levels[i], info->general.primary.string, dcerpc_server_name(p)); } } break; case 4: - if (strcmp(r.out.info->oem.oem_information.string, domain_comment) != 0) { + if (strcmp(info->oem.oem_information.string, domain_comment) != 0) { printf("QueryDomainInfo level %u returned different oem_information (comment) (%s, expected %s)\n", - levels[i], r.out.info->oem.oem_information.string, domain_comment); + levels[i], info->oem.oem_information.string, domain_comment); ret = false; } break; case 6: - if (!r.out.info->info6.primary.string) { + if (!info->info6.primary.string) { printf("QueryDomainInfo level %u returned no PDC name\n", levels[i]); ret = false; } break; case 11: - if (strcmp(r.out.info->general2.general.oem_information.string, domain_comment) != 0) { + if (strcmp(info->general2.general.oem_information.string, domain_comment) != 0) { printf("QueryDomainInfo level %u returned different comment (%s, expected %s)\n", - levels[i], r.out.info->general2.general.oem_information.string, domain_comment); + levels[i], info->general2.general.oem_information.string, domain_comment); ret = false; } break; @@ -3881,7 +4051,7 @@ static bool test_QueryDomainInfo(struct dcerpc_pipe *p, struct torture_context * s.in.domain_handle = handle; s.in.level = levels[i]; - s.in.info = r.out.info; + s.in.info = info; status = dcerpc_samr_SetDomainInfo(p, tctx, &s); if (set_ok[i]) { @@ -3918,6 +4088,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context { NTSTATUS status; struct samr_QueryDomainInfo2 r; + union samr_DomainInfo *info = NULL; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13}; int i; bool ret = true; @@ -3927,6 +4098,7 @@ static bool test_QueryDomainInfo2(struct dcerpc_pipe *p, struct torture_context r.in.domain_handle = handle; r.in.level = levels[i]; + r.out.info = &info; status = dcerpc_samr_QueryDomainInfo2(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -3949,8 +4121,13 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, struct samr_QueryDisplayInfo q2; NTSTATUS status; uint32_t resume_handle=0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; int i; bool ret = true; + uint32_t total_size; + uint32_t returned_size; + union samr_DispInfo info; int num_names = 0; const char **names = NULL; @@ -3961,6 +4138,8 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, q1.in.resume_handle = &resume_handle; q1.in.max_size = 5; q1.out.resume_handle = &resume_handle; + q1.out.num_entries = &num_entries; + q1.out.sam = &sam; status = STATUS_MORE_ENTRIES; while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { @@ -3970,22 +4149,25 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) break; - for (i=0; i<q1.out.num_entries; i++) { + for (i=0; i<*q1.out.num_entries; i++) { add_string_to_array(tctx, - q1.out.sam->entries[i].name.string, + sam->entries[i].name.string, &names, &num_names); } } torture_assert_ntstatus_ok(tctx, status, "EnumDomainGroups"); - torture_assert(tctx, q1.out.sam, "EnumDomainGroups failed to return q1.out.sam"); + torture_assert(tctx, sam, "EnumDomainGroups failed to return sam"); q2.in.domain_handle = handle; q2.in.level = 5; q2.in.start_idx = 0; q2.in.max_entries = 5; q2.in.buf_size = (uint32_t)-1; + q2.out.total_size = &total_size; + q2.out.returned_size = &returned_size; + q2.out.info = &info; status = STATUS_MORE_ENTRIES; while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { @@ -3995,9 +4177,9 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, !NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) break; - for (i=0; i<q2.out.info.info5.count; i++) { + for (i=0; i<q2.out.info->info5.count; i++) { int j; - const char *name = q2.out.info.info5.entries[i].account_name.string; + const char *name = q2.out.info->info5.entries[i].account_name.string; bool found = false; for (j=0; j<num_names; j++) { if (names[j] == NULL) @@ -4015,7 +4197,7 @@ static bool test_GroupList(struct dcerpc_pipe *p, struct torture_context *tctx, ret = false; } } - q2.in.start_idx += q2.out.info.info5.count; + q2.in.start_idx += q2.out.info->info5.count; } if (!NT_STATUS_IS_OK(status)) { @@ -4076,7 +4258,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx, struct samr_RidToSid r; NTSTATUS status; bool ret = true; - struct dom_sid *calc_sid; + struct dom_sid *calc_sid, *out_sid; int rids[] = { 0, 42, 512, 10200 }; int i; @@ -4086,6 +4268,7 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx, calc_sid = dom_sid_dup(tctx, domain_sid); r.in.domain_handle = domain_handle; r.in.rid = rids[i]; + r.out.sid = &out_sid; status = dcerpc_samr_RidToSid(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -4094,9 +4277,9 @@ static bool test_RidToSid(struct dcerpc_pipe *p, struct torture_context *tctx, } else { calc_sid = dom_sid_add_rid(calc_sid, calc_sid, rids[i]); - if (!dom_sid_equal(calc_sid, r.out.sid)) { + if (!dom_sid_equal(calc_sid, out_sid)) { printf("RidToSid for %d failed - got %s, expected %s\n", rids[i], - dom_sid_string(tctx, r.out.sid), + dom_sid_string(tctx, out_sid), dom_sid_string(tctx, calc_sid)); ret = false; } @@ -4112,10 +4295,12 @@ static bool test_GetBootKeyInformation(struct dcerpc_pipe *p, struct torture_con struct samr_GetBootKeyInformation r; NTSTATUS status; bool ret = true; + uint32_t unknown = 0; torture_comment(tctx, "Testing GetBootKeyInformation\n"); r.in.domain_handle = domain_handle; + r.out.unknown = &unknown; status = dcerpc_samr_GetBootKeyInformation(p, tctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -4134,6 +4319,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t struct samr_AddGroupMember r; struct samr_DeleteGroupMember d; struct samr_QueryGroupMember q; + struct samr_RidTypeArray *rids = NULL; struct samr_SetMemberAttributesOfGroup s; uint32_t rid; @@ -4173,6 +4359,7 @@ static bool test_AddGroupMember(struct dcerpc_pipe *p, struct torture_context *t } q.in.group_handle = group_handle; + q.out.rids = &rids; status = dcerpc_samr_QueryGroupMember(p, tctx, &q); torture_assert_ntstatus_ok(tctx, status, "QueryGroupMember"); @@ -4388,6 +4575,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct { NTSTATUS status; struct samr_LookupDomain r; + struct dom_sid2 *sid = NULL; struct lsa_String n1; struct lsa_String n2; bool ret = true; @@ -4397,6 +4585,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct /* check for correct error codes */ r.in.connect_handle = handle; r.in.domain_name = &n2; + r.out.sid = &sid; n2.string = NULL; status = dcerpc_samr_LookupDomain(p, tctx, &r); @@ -4419,7 +4608,7 @@ static bool test_LookupDomain(struct dcerpc_pipe *p, struct torture_context *tct ret = false; } - if (!test_OpenDomain(p, tctx, handle, r.out.sid, which_ops)) { + if (!test_OpenDomain(p, tctx, handle, *r.out.sid, which_ops)) { ret = false; } @@ -4433,6 +4622,8 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx NTSTATUS status; struct samr_EnumDomains r; uint32_t resume_handle = 0; + uint32_t num_entries = 0; + struct samr_SamArray *sam = NULL; int i; bool ret = true; @@ -4440,17 +4631,19 @@ static bool test_EnumDomains(struct dcerpc_pipe *p, struct torture_context *tctx r.in.resume_handle = &resume_handle; r.in.buf_size = (uint32_t)-1; r.out.resume_handle = &resume_handle; + r.out.num_entries = &num_entries; + r.out.sam = &sam; status = dcerpc_samr_EnumDomains(p, tctx, &r); torture_assert_ntstatus_ok(tctx, status, "EnumDomains"); - if (!r.out.sam) { + if (!*r.out.sam) { return false; } - for (i=0;i<r.out.sam->count;i++) { + for (i=0;i<sam->count;i++) { if (!test_LookupDomain(p, tctx, handle, - r.out.sam->entries[i].name.string, which_ops)) { + sam->entries[i].name.string, which_ops)) { ret = false; } } @@ -4473,6 +4666,7 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx, struct samr_Connect5 r5; union samr_ConnectInfo info; struct policy_handle h; + uint32_t level_out = 0; bool ret = true, got_handle = false; torture_comment(tctx, "testing samr_Connect\n"); @@ -4553,9 +4747,10 @@ static bool test_Connect(struct dcerpc_pipe *p, struct torture_context *tctx, r5.in.system_name = ""; r5.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - r5.in.level = 1; - r5.in.info = &info; - r5.out.info = &info; + r5.in.level_in = 1; + r5.out.level_out = &level_out; + r5.in.info_in = &info; + r5.out.info_out = &info; r5.out.connect_handle = &h; status = dcerpc_samr_Connect5(p, tctx, &r5); diff --git a/source4/torture/rpc/samr_accessmask.c b/source4/torture/rpc/samr_accessmask.c index bfff8c9267..9a8e442019 100644 --- a/source4/torture/rpc/samr_accessmask.c +++ b/source4/torture/rpc/samr_accessmask.c @@ -52,13 +52,15 @@ static NTSTATUS torture_samr_Connect5(struct torture_context *tctx, NTSTATUS status; struct samr_Connect5 r5; union samr_ConnectInfo info; + uint32_t level_out = 0; info.info1.client_version = 0; info.info1.unknown2 = 0; r5.in.system_name = ""; - r5.in.level = 1; - r5.in.info = &info; - r5.out.info = &info; + r5.in.level_in = 1; + r5.in.info_in = &info; + r5.out.info_out = &info; + r5.out.level_out = &level_out; r5.out.connect_handle = h; r5.in.access_mask = mask; @@ -147,6 +149,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx, int i; uint32_t mask; uint32_t resume_handle = 0; + struct samr_SamArray *sam = NULL; + uint32_t num_entries = 0; printf("testing which bits in Connect5 accessmask allows us to EnumDomains\n"); mask = 1; @@ -170,6 +174,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx, ed.in.resume_handle = &resume_handle; ed.in.buf_size = (uint32_t)-1; ed.out.resume_handle = &resume_handle; + ed.out.num_entries = &num_entries; + ed.out.sam = &sam; status = dcerpc_samr_EnumDomains(p, tctx, &ed); if (!NT_STATUS_IS_OK(status)) { @@ -195,6 +201,8 @@ static bool test_samr_accessmask_EnumDomains(struct torture_context *tctx, ed.in.resume_handle = &resume_handle; ed.in.buf_size = (uint32_t)-1; ed.out.resume_handle = &resume_handle; + ed.out.num_entries = &num_entries; + ed.out.sam = &sam; status = dcerpc_samr_EnumDomains(p, tctx, &ed); if(!NT_STATUS_EQUAL(NT_STATUS_ACCESS_DENIED, status)) { @@ -236,7 +244,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, struct samr_SetSecurity ss; struct security_ace ace; struct security_descriptor *sd; - struct sec_desc_buf sdb; + struct sec_desc_buf sdb, *sdbuf = NULL; bool ret = true; int sd_size; struct dcerpc_pipe *test_p; @@ -255,6 +263,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, /* get the current ACL for the SAMR policy handle */ qs.in.handle = &ch; qs.in.sec_info = SECINFO_DACL; + qs.out.sdbuf = &sdbuf; status = dcerpc_samr_QuerySecurity(p, tctx, &qs); if (!NT_STATUS_IS_OK(status)) { printf("QuerySecurity failed - %s\n", nt_errstr(status)); @@ -262,13 +271,13 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, } /* how big is the security descriptor? */ - sd_size = qs.out.sdbuf->sd_size; + sd_size = sdbuf->sd_size; /* add an ACE to the security descriptor to deny the user the * 'connect to server' right */ - sd = qs.out.sdbuf->sd; + sd = sdbuf->sd; ace.type = SEC_ACE_TYPE_ACCESS_DENIED; ace.flags = 0; ace.access_mask = SAMR_ACCESS_CONNECT_TO_SERVER; @@ -314,7 +323,7 @@ static bool test_samr_connect_user_acl(struct torture_context *tctx, printf("QuerySecurity failed - %s\n", nt_errstr(status)); ret = false; } - if (sd_size != qs.out.sdbuf->sd_size) { + if (sd_size != sdbuf->sd_size) { printf("security descriptor changed\n"); ret = false; } @@ -387,6 +396,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx, { NTSTATUS status; struct samr_LookupDomain ld; + struct dom_sid2 *sid = NULL; struct policy_handle ch; struct lsa_String dn; int i; @@ -412,6 +422,7 @@ static bool test_samr_accessmask_LookupDomain(struct torture_context *tctx, ld.in.connect_handle = &ch; ld.in.domain_name = &dn; + ld.out.sid = &sid; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); @@ -471,6 +482,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, { NTSTATUS status; struct samr_LookupDomain ld; + struct dom_sid2 *sid = NULL; struct samr_OpenDomain od; struct policy_handle ch; struct policy_handle dh; @@ -488,6 +500,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, ld.in.connect_handle = &ch; ld.in.domain_name = &dn; + ld.out.sid = &sid; dn.string = lp_workgroup(tctx->lp_ctx); status = dcerpc_samr_LookupDomain(p, tctx, &ld); if (!NT_STATUS_IS_OK(status)) { @@ -517,7 +530,7 @@ static bool test_samr_accessmask_OpenDomain(struct torture_context *tctx, od.in.connect_handle = &ch; od.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - od.in.sid = ld.out.sid; + od.in.sid = *ld.out.sid; od.out.domain_handle = &dh; status = dcerpc_samr_OpenDomain(p, tctx, &od); diff --git a/source4/torture/rpc/samsync.c b/source4/torture/rpc/samsync.c index 12ddc934c9..a3fc6f740f 100644 --- a/source4/torture/rpc/samsync.c +++ b/source4/torture/rpc/samsync.c @@ -151,17 +151,19 @@ struct samsync_trusted_domain { static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, struct samsync_state *samsync_state, const char *domain, - struct dom_sid **sid) + struct dom_sid **sid_p) { struct lsa_String name; struct samr_OpenDomain o; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; struct policy_handle *domain_handle = talloc(mem_ctx, struct policy_handle); NTSTATUS nt_status; name.string = domain; l.in.connect_handle = samsync_state->connect_handle; l.in.domain_name = &name; + l.out.sid = &sid; nt_status = dcerpc_samr_LookupDomain(samsync_state->p_samr, mem_ctx, &l); if (!NT_STATUS_IS_OK(nt_status)) { @@ -171,11 +173,11 @@ static struct policy_handle *samsync_open_domain(TALLOC_CTX *mem_ctx, o.in.connect_handle = samsync_state->connect_handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - o.in.sid = l.out.sid; + o.in.sid = *l.out.sid; o.out.domain_handle = domain_handle; if (sid) { - *sid = l.out.sid; + *sid_p = *l.out.sid; } nt_status = dcerpc_samr_OpenDomain(samsync_state->p_samr, mem_ctx, &o); @@ -192,10 +194,12 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx, struct policy_handle *handle) { struct samr_QuerySecurity r; + struct sec_desc_buf *sdbuf = NULL; NTSTATUS status; r.in.handle = handle; r.in.sec_info = 0x7; + r.out.sdbuf = &sdbuf; status = dcerpc_samr_QuerySecurity(samsync_state->p_samr, mem_ctx, &r); if (!NT_STATUS_IS_OK(status)) { @@ -203,7 +207,7 @@ static struct sec_desc_buf *samsync_query_samr_sec_desc(TALLOC_CTX *mem_ctx, return NULL; } - return r.out.sdbuf; + return sdbuf; } static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx, @@ -260,6 +264,15 @@ static struct sec_desc_buf *samsync_query_lsa_sec_desc(TALLOC_CTX *mem_ctx, } \ } while (0) +#define TEST_BINARY_STRING_EQUAL(s1, s2) do {\ + if (!((!s1.array || s1.array[0]=='\0') && (!s2.array || s2.array[0]=='\0')) \ + && memcmp(s1.array, s2.array, s1.length * 2) != 0) {\ + printf("%s: string mismatch: " #s1 ":%s != " #s2 ": %s\n", \ + __location__, (const char *)s1.array, (const char *)s2.array);\ + ret = false;\ + } \ +} while (0) + #define TEST_SID_EQUAL(s1, s2) do {\ if (!dom_sid_equal(s1, s2)) {\ printf("%s: dom_sid mismatch: " #s1 ":%s != " #s2 ": %s\n", \ @@ -294,6 +307,7 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam struct netr_DELTA_DOMAIN *domain = delta->delta_union.domain; struct dom_sid *dom_sid; struct samr_QueryDomainInfo q[14]; /* q[0] will be unused simple for clarity */ + union samr_DomainInfo *info[14]; uint16_t levels[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13}; NTSTATUS nt_status; int i; @@ -341,8 +355,10 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam (long long)samsync_state->seq_num[database_id]); for (i=0;i<ARRAY_SIZE(levels);i++) { + q[levels[i]].in.domain_handle = samsync_state->domain_handle[database_id]; q[levels[i]].in.level = levels[i]; + q[levels[i]].out.info = &info[levels[i]]; nt_status = dcerpc_samr_QueryDomainInfo(samsync_state->p_samr, mem_ctx, &q[levels[i]]); @@ -353,23 +369,23 @@ static bool samsync_handle_domain(TALLOC_CTX *mem_ctx, struct samsync_state *sam } } - TEST_STRING_EQUAL(q[5].out.info->info5.domain_name, domain->domain_name); + TEST_STRING_EQUAL(info[5]->info5.domain_name, domain->domain_name); - TEST_STRING_EQUAL(q[2].out.info->general.oem_information, domain->oem_information); - TEST_STRING_EQUAL(q[4].out.info->oem.oem_information, domain->oem_information); - TEST_TIME_EQUAL(q[2].out.info->general.force_logoff_time, domain->force_logoff_time); - TEST_TIME_EQUAL(q[3].out.info->info3.force_logoff_time, domain->force_logoff_time); + TEST_STRING_EQUAL(info[2]->general.oem_information, domain->oem_information); + TEST_STRING_EQUAL(info[4]->oem.oem_information, domain->oem_information); + TEST_TIME_EQUAL(info[2]->general.force_logoff_time, domain->force_logoff_time); + TEST_TIME_EQUAL(info[3]->info3.force_logoff_time, domain->force_logoff_time); - TEST_TIME_EQUAL(q[1].out.info->info1.min_password_length, domain->min_password_length); - TEST_TIME_EQUAL(q[1].out.info->info1.password_history_length, domain->password_history_length); - TEST_TIME_EQUAL(q[1].out.info->info1.max_password_age, domain->max_password_age); - TEST_TIME_EQUAL(q[1].out.info->info1.min_password_age, domain->min_password_age); + TEST_TIME_EQUAL(info[1]->info1.min_password_length, domain->min_password_length); + TEST_TIME_EQUAL(info[1]->info1.password_history_length, domain->password_history_length); + TEST_TIME_EQUAL(info[1]->info1.max_password_age, domain->max_password_age); + TEST_TIME_EQUAL(info[1]->info1.min_password_age, domain->min_password_age); - TEST_UINT64_EQUAL(q[8].out.info->info8.sequence_num, + TEST_UINT64_EQUAL(info[8]->info8.sequence_num, domain->sequence_num); - TEST_TIME_EQUAL(q[8].out.info->info8.domain_create_time, + TEST_TIME_EQUAL(info[8]->info8.domain_create_time, domain->domain_create_time); - TEST_TIME_EQUAL(q[13].out.info->info13.domain_create_time, + TEST_TIME_EQUAL(info[13]->info13.domain_create_time, domain->domain_create_time); TEST_SEC_DESC_EQUAL(domain->sdbuf, samr, samsync_state->domain_handle[database_id]); @@ -425,9 +441,12 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct struct samr_OpenUser r; struct samr_QueryUserInfo q; + union samr_UserInfo *info; struct policy_handle user_handle; struct samr_GetGroupsForUser getgroups; + struct samr_RidWithAttributeArray *rids; + if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) { printf("SamSync needs domain information before the users\n"); return false; @@ -446,6 +465,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct q.in.user_handle = &user_handle; q.in.level = 21; + q.out.info = &info; TEST_SEC_DESC_EQUAL(user->sdbuf, samr, &user_handle); @@ -457,6 +477,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct } getgroups.in.user_handle = &user_handle; + getgroups.out.rids = &rids; nt_status = dcerpc_samr_GetGroupsForUser(samsync_state->p_samr, mem_ctx, &getgroups); if (!NT_STATUS_IS_OK(nt_status)) { @@ -480,67 +501,67 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct return false; } - TEST_STRING_EQUAL(q.out.info->info21.account_name, user->account_name); - TEST_STRING_EQUAL(q.out.info->info21.full_name, user->full_name); - TEST_INT_EQUAL(q.out.info->info21.rid, user->rid); - TEST_INT_EQUAL(q.out.info->info21.primary_gid, user->primary_gid); - TEST_STRING_EQUAL(q.out.info->info21.home_directory, user->home_directory); - TEST_STRING_EQUAL(q.out.info->info21.home_drive, user->home_drive); - TEST_STRING_EQUAL(q.out.info->info21.logon_script, user->logon_script); - TEST_STRING_EQUAL(q.out.info->info21.description, user->description); - TEST_STRING_EQUAL(q.out.info->info21.workstations, user->workstations); + TEST_STRING_EQUAL(info->info21.account_name, user->account_name); + TEST_STRING_EQUAL(info->info21.full_name, user->full_name); + TEST_INT_EQUAL(info->info21.rid, user->rid); + TEST_INT_EQUAL(info->info21.primary_gid, user->primary_gid); + TEST_STRING_EQUAL(info->info21.home_directory, user->home_directory); + TEST_STRING_EQUAL(info->info21.home_drive, user->home_drive); + TEST_STRING_EQUAL(info->info21.logon_script, user->logon_script); + TEST_STRING_EQUAL(info->info21.description, user->description); + TEST_STRING_EQUAL(info->info21.workstations, user->workstations); - TEST_TIME_EQUAL(q.out.info->info21.last_logon, user->last_logon); - TEST_TIME_EQUAL(q.out.info->info21.last_logoff, user->last_logoff); + TEST_TIME_EQUAL(info->info21.last_logon, user->last_logon); + TEST_TIME_EQUAL(info->info21.last_logoff, user->last_logoff); - TEST_INT_EQUAL(q.out.info->info21.logon_hours.units_per_week, + TEST_INT_EQUAL(info->info21.logon_hours.units_per_week, user->logon_hours.units_per_week); if (ret) { - if (memcmp(q.out.info->info21.logon_hours.bits, user->logon_hours.bits, - q.out.info->info21.logon_hours.units_per_week/8) != 0) { + if (memcmp(info->info21.logon_hours.bits, user->logon_hours.bits, + info->info21.logon_hours.units_per_week/8) != 0) { printf("Logon hours mismatch\n"); ret = false; } } - TEST_INT_EQUAL(q.out.info->info21.bad_password_count, + TEST_INT_EQUAL(info->info21.bad_password_count, user->bad_password_count); - TEST_INT_EQUAL(q.out.info->info21.logon_count, + TEST_INT_EQUAL(info->info21.logon_count, user->logon_count); - TEST_TIME_EQUAL(q.out.info->info21.last_password_change, + TEST_TIME_EQUAL(info->info21.last_password_change, user->last_password_change); - TEST_TIME_EQUAL(q.out.info->info21.acct_expiry, + TEST_TIME_EQUAL(info->info21.acct_expiry, user->acct_expiry); - TEST_INT_EQUAL((q.out.info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags); + TEST_INT_EQUAL((info->info21.acct_flags & ~ACB_PW_EXPIRED), user->acct_flags); if (user->acct_flags & ACB_PWNOEXP) { - if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) { + if (info->info21.acct_flags & ACB_PW_EXPIRED) { printf("ACB flags mismatch: both expired and no expiry!\n"); ret = false; } - if (q.out.info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) { + if (info->info21.force_password_change != (NTTIME)0x7FFFFFFFFFFFFFFFULL) { printf("ACB flags mismatch: no password expiry, but force password change 0x%016llx (%lld) != 0x%016llx (%lld)\n", - (unsigned long long)q.out.info->info21.force_password_change, - (unsigned long long)q.out.info->info21.force_password_change, + (unsigned long long)info->info21.force_password_change, + (unsigned long long)info->info21.force_password_change, (unsigned long long)0x7FFFFFFFFFFFFFFFULL, (unsigned long long)0x7FFFFFFFFFFFFFFFULL ); ret = false; } } - TEST_INT_EQUAL(q.out.info->info21.nt_password_set, user->nt_password_present); - TEST_INT_EQUAL(q.out.info->info21.lm_password_set, user->lm_password_present); - TEST_INT_EQUAL(q.out.info->info21.password_expired, user->password_expired); + TEST_INT_EQUAL(info->info21.nt_password_set, user->nt_password_present); + TEST_INT_EQUAL(info->info21.lm_password_set, user->lm_password_present); + TEST_INT_EQUAL(info->info21.password_expired, user->password_expired); - TEST_STRING_EQUAL(q.out.info->info21.comment, user->comment); - TEST_STRING_EQUAL(q.out.info->info21.parameters, user->parameters); + TEST_STRING_EQUAL(info->info21.comment, user->comment); + TEST_BINARY_STRING_EQUAL(info->info21.parameters, user->parameters); - TEST_INT_EQUAL(q.out.info->info21.country_code, user->country_code); - TEST_INT_EQUAL(q.out.info->info21.code_page, user->code_page); + TEST_INT_EQUAL(info->info21.country_code, user->country_code); + TEST_INT_EQUAL(info->info21.code_page, user->code_page); - TEST_STRING_EQUAL(q.out.info->info21.profile_path, user->profile_path); + TEST_STRING_EQUAL(info->info21.profile_path, user->profile_path); if (user->lm_password_present) { sam_rid_crypt(rid, user->lmpassword.hash, lm_hash.hash, 0); @@ -619,7 +640,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct return true; } } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_PASSWORD_EXPIRED)) { - if (q.out.info->info21.acct_flags & ACB_PW_EXPIRED) { + if (info->info21.acct_flags & ACB_PW_EXPIRED) { return true; } } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_WRONG_PASSWORD)) { @@ -654,7 +675,7 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct TEST_TIME_EQUAL(user->last_logon, info3->base.last_logon); TEST_TIME_EQUAL(user->acct_expiry, info3->base.acct_expiry); TEST_TIME_EQUAL(user->last_password_change, info3->base.last_password_change); - TEST_TIME_EQUAL(q.out.info->info21.force_password_change, info3->base.force_password_change); + TEST_TIME_EQUAL(info->info21.force_password_change, info3->base.force_password_change); /* Does the concept of a logoff time ever really * exist? (not in any sensible way, according to the @@ -667,28 +688,28 @@ static bool samsync_handle_user(struct torture_context *tctx, TALLOC_CTX *mem_ct TEST_TIME_EQUAL(user->last_logoff, info3->base.last_logoff); } - TEST_INT_EQUAL(getgroups.out.rids->count, info3->base.groups.count); - if (getgroups.out.rids->count == info3->base.groups.count) { + TEST_INT_EQUAL(rids->count, info3->base.groups.count); + if (rids->count == info3->base.groups.count) { int i, j; - int count = getgroups.out.rids->count; - bool *matched = talloc_zero_array(mem_ctx, bool, getgroups.out.rids->count); + int count = rids->count; + bool *matched = talloc_zero_array(mem_ctx, bool, rids->count); for (i = 0; i < count; i++) { for (j = 0; j < count; j++) { - if ((getgroups.out.rids->rids[i].rid == + if ((rids->rids[i].rid == info3->base.groups.rids[j].rid) - && (getgroups.out.rids->rids[i].attributes == + && (rids->rids[i].attributes == info3->base.groups.rids[j].attributes)) { matched[i] = true; } } } - for (i = 0; i < getgroups.out.rids->count; i++) { + for (i = 0; i < rids->count; i++) { if (matched[i] == false) { ret = false; printf("Could not find group RID %u found in getgroups in NETLOGON reply\n", - getgroups.out.rids->rids[i].rid); + rids->rids[i].rid); } } } @@ -711,6 +732,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams struct samr_OpenAlias r; struct samr_QueryAliasInfo q; + union samr_AliasInfo *info; struct policy_handle alias_handle; if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) { @@ -731,6 +753,7 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams q.in.alias_handle = &alias_handle; q.in.level = 1; + q.out.info = &info; TEST_SEC_DESC_EQUAL(alias->sdbuf, samr, &alias_handle); @@ -745,8 +768,8 @@ static bool samsync_handle_alias(TALLOC_CTX *mem_ctx, struct samsync_state *sams return false; } - TEST_STRING_EQUAL(q.out.info->all.name, alias->alias_name); - TEST_STRING_EQUAL(q.out.info->all.description, alias->description); + TEST_STRING_EQUAL(info->all.name, alias->alias_name); + TEST_STRING_EQUAL(info->all.description, alias->description); return ret; } @@ -760,6 +783,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams struct samr_OpenGroup r; struct samr_QueryGroupInfo q; + union samr_GroupInfo *info; struct policy_handle group_handle; if (!samsync_state->domain_name || !samsync_state->domain_handle[database_id]) { @@ -780,6 +804,7 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams q.in.group_handle = &group_handle; q.in.level = 1; + q.out.info = &info; TEST_SEC_DESC_EQUAL(group->sdbuf, samr, &group_handle); @@ -794,9 +819,9 @@ static bool samsync_handle_group(TALLOC_CTX *mem_ctx, struct samsync_state *sams return false; } - TEST_STRING_EQUAL(q.out.info->all.name, group->group_name); - TEST_INT_EQUAL(q.out.info->all.attributes, group->attributes); - TEST_STRING_EQUAL(q.out.info->all.description, group->description); + TEST_STRING_EQUAL(info->all.name, group->group_name); + TEST_INT_EQUAL(info->all.attributes, group->attributes); + TEST_STRING_EQUAL(info->all.description, group->description); return ret; } diff --git a/source4/torture/rpc/schannel.c b/source4/torture/rpc/schannel.c index 2c39596e35..451990a71b 100644 --- a/source4/torture/rpc/schannel.c +++ b/source4/torture/rpc/schannel.c @@ -128,6 +128,7 @@ static bool test_samr_ops(struct torture_context *tctx, { NTSTATUS status; struct samr_GetDomPwInfo r; + struct samr_PwInfo info; struct samr_Connect connect; struct samr_OpenDomain opendom; int i; @@ -137,6 +138,7 @@ static bool test_samr_ops(struct torture_context *tctx, name.string = lp_workgroup(tctx->lp_ctx); r.in.domain_name = &name; + r.out.info = &info; connect.in.system_name = 0; connect.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; @@ -292,7 +294,7 @@ static bool test_schannel(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "seconday connection"); status = dcerpc_bind_auth(p_netlogon, &ndr_table_netlogon, - credentials, tctx->lp_ctx, + credentials, lp_gensec_settings(tctx, tctx->lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p->conn), NULL); @@ -319,7 +321,7 @@ static bool test_schannel(struct torture_context *tctx, torture_assert_ntstatus_ok(tctx, status, "seconday connection"); status = dcerpc_bind_auth(p_lsa, &ndr_table_lsarpc, - credentials, tctx->lp_ctx, + credentials, lp_gensec_settings(tctx, tctx->lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p->conn), NULL); @@ -360,7 +362,7 @@ static bool test_schannel(struct torture_context *tctx, /* and now setup an SCHANNEL bind on netlogon */ status = dcerpc_bind_auth(p_netlogon2, &ndr_table_netlogon, - credentials, tctx->lp_ctx, + credentials, lp_gensec_settings(tctx, tctx->lp_ctx), DCERPC_AUTH_TYPE_SCHANNEL, dcerpc_auth_level(p_samr2->conn), NULL); diff --git a/source4/torture/rpc/spoolss_notify.c b/source4/torture/rpc/spoolss_notify.c index dc2a82414b..f9ff31a797 100644 --- a/source4/torture/rpc/spoolss_notify.c +++ b/source4/torture/rpc/spoolss_notify.c @@ -60,7 +60,8 @@ static NTSTATUS spoolss__op_ndr_pull(struct dcesrv_call_state *dce_call, TALLOC_ /* unravel the NDR for the packet */ ndr_err = ndr_table_spoolss.calls[opnum].ndr_pull(pull, NDR_IN, *r); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - dcerpc_log_packet(&ndr_table_spoolss, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_spoolss, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); dce_call->fault_code = DCERPC_FAULT_NDR; return NT_STATUS_NET_WRITE_FAULT; @@ -102,7 +103,8 @@ static NTSTATUS spoolss__op_dispatch(struct dcesrv_call_state *dce_call, TALLOC_ } if (dce_call->fault_code != 0) { - dcerpc_log_packet(&ndr_table_spoolss, opnum, NDR_IN, + dcerpc_log_packet(dce_call->conn->packet_log_dir, + &ndr_table_spoolss, opnum, NDR_IN, &dce_call->pkt.u.request.stub_and_verifier); return NT_STATUS_NET_WRITE_FAULT; } diff --git a/source4/torture/rpc/testjoin.c b/source4/torture/rpc/testjoin.c index 3408a1924c..3b56d5b0ad 100644 --- a/source4/torture/rpc/testjoin.c +++ b/source4/torture/rpc/testjoin.c @@ -59,6 +59,7 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, struct policy_handle user_handle; uint32_t rid; struct samr_LookupNames n; + struct samr_Ids rids, types; struct lsa_String sname; struct samr_OpenUser r; @@ -67,10 +68,12 @@ static NTSTATUS DeleteUser_byname(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx, n.in.domain_handle = handle; n.in.num_names = 1; n.in.names = &sname; + n.out.rids = &rids; + n.out.types = &types; status = dcerpc_samr_LookupNames(p, mem_ctx, &n); if (NT_STATUS_IS_OK(status)) { - rid = n.out.rids.ids[0]; + rid = n.out.rids->ids[0]; } else { return status; } @@ -113,7 +116,9 @@ struct test_join *torture_create_testuser(struct torture_context *torture, struct samr_CreateUser2 r; struct samr_OpenDomain o; struct samr_LookupDomain l; + struct dom_sid2 *sid = NULL; struct samr_GetUserPwInfo pwp; + struct samr_PwInfo info; struct samr_SetUserInfo s; union samr_UserInfo u; struct policy_handle handle; @@ -172,6 +177,7 @@ struct test_join *torture_create_testuser(struct torture_context *torture, name.string = domain; l.in.connect_handle = &handle; l.in.domain_name = &name; + l.out.sid = &sid; status = dcerpc_samr_LookupDomain(join->p, join, &l); if (!NT_STATUS_IS_OK(status)) { @@ -179,14 +185,14 @@ struct test_join *torture_create_testuser(struct torture_context *torture, goto failed; } - talloc_steal(join, l.out.sid); - join->dom_sid = l.out.sid; + talloc_steal(join, *l.out.sid); + join->dom_sid = *l.out.sid; join->dom_netbios_name = talloc_strdup(join, domain); if (!join->dom_netbios_name) goto failed; o.in.connect_handle = &handle; o.in.access_mask = SEC_FLAG_MAXIMUM_ALLOWED; - o.in.sid = l.out.sid; + o.in.sid = *l.out.sid; o.out.domain_handle = &domain_handle; status = dcerpc_samr_OpenDomain(join->p, join, &o); @@ -224,10 +230,11 @@ again: join->user_sid = dom_sid_add_rid(join, join->dom_sid, rid); pwp.in.user_handle = &join->user_handle; + pwp.out.info = &info; status = dcerpc_samr_GetUserPwInfo(join->p, join, &pwp); if (NT_STATUS_IS_OK(status)) { - policy_min_pw_len = pwp.out.info.min_password_length; + policy_min_pw_len = pwp.out.info->min_password_length; } random_pw = generate_random_str(join, MAX(8, policy_min_pw_len)); diff --git a/source4/torture/smb2/scan.c b/source4/torture/smb2/scan.c index ae51af1882..a5e682c111 100644 --- a/source4/torture/smb2/scan.c +++ b/source4/torture/smb2/scan.c @@ -204,10 +204,13 @@ bool torture_smb2_scan(struct torture_context *torture) lp_smbcli_options(torture->lp_ctx, &options); - status = smb2_connect(mem_ctx, host, share, - lp_resolve_context(torture->lp_ctx), - credentials, &tree, - torture->ev, &options); + status = smb2_connect(mem_ctx, host, + lp_smb_ports(torture->lp_ctx), + share, + lp_resolve_context(torture->lp_ctx), + credentials, &tree, torture->ev, &options, + lp_socket_options(torture->lp_ctx), + lp_gensec_settings(torture, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("Connection failed - %s\n", nt_errstr(status)); return false; @@ -221,10 +224,13 @@ bool torture_smb2_scan(struct torture_context *torture) smb2_transport_send(req); if (!smb2_request_receive(req)) { talloc_free(tree); - status = smb2_connect(mem_ctx, host, share, - lp_resolve_context(torture->lp_ctx), - credentials, &tree, - torture->ev, &options); + status = smb2_connect(mem_ctx, host, + lp_smb_ports(torture->lp_ctx), + share, + lp_resolve_context(torture->lp_ctx), + credentials, &tree, torture->ev, &options, + lp_socket_options(torture->lp_ctx), + lp_gensec_settings(mem_ctx, torture->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("Connection failed - %s\n", nt_errstr(status)); return false; diff --git a/source4/torture/smb2/util.c b/source4/torture/smb2/util.c index 3a437acbab..b17dc246e3 100644 --- a/source4/torture/smb2/util.c +++ b/source4/torture/smb2/util.c @@ -274,10 +274,15 @@ bool torture_smb2_connection(struct torture_context *tctx, struct smb2_tree **tr lp_smbcli_options(tctx->lp_ctx, &options); - status = smb2_connect(tctx, host, share, + status = smb2_connect(tctx, host, + lp_smb_ports(tctx->lp_ctx), + share, lp_resolve_context(tctx->lp_ctx), credentials, tree, - tctx->ev, &options); + tctx->ev, &options, + lp_socket_options(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx) + ); if (!NT_STATUS_IS_OK(status)) { printf("Failed to connect to SMB2 share \\\\%s\\%s - %s\n", host, share, nt_errstr(status)); diff --git a/source4/torture/smbtorture.c b/source4/torture/smbtorture.c index 19f1d1ae35..0c2c8c0f6b 100644 --- a/source4/torture/smbtorture.c +++ b/source4/torture/smbtorture.c @@ -33,6 +33,7 @@ #include "torture/smbtorture.h" #include "../lib/util/dlinklist.h" #include "librpc/rpc/dcerpc.h" +#include "auth/gensec/gensec.h" #include "param/param.h" #include "auth/credentials/credentials.h" @@ -370,7 +371,7 @@ static void quiet_suite_start(struct torture_context *ctx, struct torture_suite *suite) { int i; - ctx->quiet = true; + ctx->results->quiet = true; for (i = 1; i < ctx->level; i++) putchar('\t'); printf("%s: ", suite->name); fflush(stdout); @@ -456,6 +457,7 @@ int main(int argc,char *argv[]) int max_runtime=0; int argc_new; struct torture_context *torture; + struct torture_results *results; const struct torture_ui_ops *ui_ops; char **argv_new; poptContext pc; @@ -627,7 +629,9 @@ int main(int argc,char *argv[]) exit(1); } - torture = torture_context_init(s4_event_context_init(NULL), ui_ops); + results = torture_results_init(talloc_autofree_context(), ui_ops); + + torture = torture_context_init(s4_event_context_init(NULL), results); if (basedir != NULL) { if (basedir[0] != '/') { fprintf(stderr, "Please specify an absolute path to --basedir\n"); @@ -645,6 +649,8 @@ int main(int argc,char *argv[]) torture->lp_ctx = cmdline_lp_ctx; + gensec_init(cmdline_lp_ctx); + if (argc_new == 0) { printf("You must specify a test to run, or 'ALL'\n"); } else if (shell) { @@ -657,7 +663,7 @@ int main(int argc,char *argv[]) } } - if (torture->returncode && correct) { + if (torture->results->returncode && correct) { return(0); } else { return(1); diff --git a/source4/torture/unix/unix_info2.c b/source4/torture/unix/unix_info2.c index 53909f645b..d0a2c3d041 100644 --- a/source4/torture/unix/unix_info2.c +++ b/source4/torture/unix/unix_info2.c @@ -63,11 +63,12 @@ static struct smbcli_state *connect_to_server(struct torture_context *tctx) status = smbcli_full_connection(tctx, &cli, host, lp_smb_ports(tctx->lp_ctx), - share, NULL, + share, NULL, lp_socket_options(tctx->lp_ctx), cmdline_credentials, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, - lp_iconv_convenience(tctx->lp_ctx)); + lp_iconv_convenience(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", diff --git a/source4/torture/unix/whoami.c b/source4/torture/unix/whoami.c index d7fbe4a23d..5e5a5e81cd 100644 --- a/source4/torture/unix/whoami.c +++ b/source4/torture/unix/whoami.c @@ -84,10 +84,11 @@ static struct smbcli_state *connect_to_server(struct torture_context *tctx, status = smbcli_full_connection(tctx, &cli, host, lp_smb_ports(tctx->lp_ctx), - share, NULL, + share, NULL, lp_socket_options(tctx->lp_ctx), creds, lp_resolve_context(tctx->lp_ctx), tctx->ev, &options, &session_options, - lp_iconv_convenience(tctx->lp_ctx)); + lp_iconv_convenience(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("failed to connect to //%s/%s: %s\n", diff --git a/source4/torture/util.h b/source4/torture/util.h index 9dc948ade5..f36d54233d 100644 --- a/source4/torture/util.h +++ b/source4/torture/util.h @@ -17,8 +17,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _TORTURE_PROVISION_H_ -#define _TORTURE_PROVISION_H_ +#ifndef _TORTURE_UTIL_H_ +#define _TORTURE_UTIL_H_ #include "torture/torture.h" @@ -94,4 +94,4 @@ NTSTATUS torture_second_tcon(TALLOC_CTX *mem_ctx, -#endif /* _TORTURE_PROVISION_H_ */ +#endif /* _TORTURE_UTIL_H_ */ diff --git a/source4/torture/util_smb.c b/source4/torture/util_smb.c index b84938cf11..ae051b9735 100644 --- a/source4/torture/util_smb.c +++ b/source4/torture/util_smb.c @@ -486,10 +486,12 @@ _PUBLIC_ bool torture_open_connection_share(TALLOC_CTX *mem_ctx, status = smbcli_full_connection(mem_ctx, c, hostname, lp_smb_ports(tctx->lp_ctx), sharename, NULL, + lp_socket_options(tctx->lp_ctx), cmdline_credentials, lp_resolve_context(tctx->lp_ctx), ev, &options, &session_options, - lp_iconv_convenience(tctx->lp_ctx)); + lp_iconv_convenience(tctx->lp_ctx), + lp_gensec_settings(tctx, tctx->lp_ctx)); if (!NT_STATUS_IS_OK(status)) { printf("Failed to open connection - %s\n", nt_errstr(status)); return false; diff --git a/source4/utils/net/net.c b/source4/utils/net/net.c index 1c834fe4f0..81584e4398 100644 --- a/source4/utils/net/net.c +++ b/source4/utils/net/net.c @@ -183,7 +183,7 @@ static int binary_net(int argc, const char **argv) return net_usage(ctx, argc, argv); } - dcerpc_init(); + dcerpc_init(cmdline_lp_ctx); ev = s4_event_context_init(NULL); if (!ev) { diff --git a/source4/utils/ntlm_auth.c b/source4/utils/ntlm_auth.c index c91d90c214..4964694790 100644 --- a/source4/utils/ntlm_auth.c +++ b/source4/utils/ntlm_auth.c @@ -212,7 +212,8 @@ static NTSTATUS local_pw_check_specified(struct loadparm_context *lp_ctx, nt_status = ntlm_password_check(mem_ctx, - lp_ctx, + lp_lanman_auth(lp_ctx), + lp_ntlm_auth(lp_ctx), MSV1_0_ALLOW_SERVER_TRUST_ACCOUNT | MSV1_0_ALLOW_WORKSTATION_TRUST_ACCOUNT, challenge, @@ -472,7 +473,8 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, case NTLMSSP_CLIENT_1: /* setup the client side */ - nt_status = gensec_client_start(NULL, &state->gensec_state, ev, lp_ctx); + nt_status = gensec_client_start(NULL, &state->gensec_state, ev, + lp_gensec_settings(NULL, lp_ctx)); if (!NT_STATUS_IS_OK(nt_status)) { exit(1); } @@ -485,7 +487,8 @@ static void manage_gensec_request(enum stdio_helper_mode stdio_helper_mode, if (!msg) { exit(1); } - if (!NT_STATUS_IS_OK(gensec_server_start(state, ev, lp_ctx, msg, &state->gensec_state))) { + if (!NT_STATUS_IS_OK(gensec_server_start(state, ev, lp_gensec_settings(state, lp_ctx), + msg, &state->gensec_state))) { exit(1); } break; diff --git a/source4/winbind/wb_async_helpers.c b/source4/winbind/wb_async_helpers.c index 48a2a4d882..a50a0fe473 100644 --- a/source4/winbind/wb_async_helpers.c +++ b/source4/winbind/wb_async_helpers.c @@ -325,6 +325,8 @@ struct samr_getuserdomgroups_state { int num_rids; uint32_t *rids; + struct samr_RidWithAttributeArray *rid_array; + struct policy_handle *user_handle; struct samr_OpenUser o; struct samr_GetGroupsForUser g; @@ -386,6 +388,7 @@ static void samr_usergroups_recv_open(struct rpc_request *req) if (!composite_is_ok(state->ctx)) return; state->g.in.user_handle = state->user_handle; + state->g.out.rids = &state->rid_array; req = dcerpc_samr_GetGroupsForUser_send(state->samr_pipe, state, &state->g); @@ -438,7 +441,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx, NTSTATUS status = composite_wait(ctx); if (!NT_STATUS_IS_OK(status)) goto done; - *num_rids = state->g.out.rids->count; + *num_rids = state->rid_array->count; *rids = talloc_array(mem_ctx, uint32_t, *num_rids); if (*rids == NULL) { status = NT_STATUS_NO_MEMORY; @@ -446,7 +449,7 @@ NTSTATUS wb_samr_userdomgroups_recv(struct composite_context *ctx, } for (i=0; i<*num_rids; i++) { - (*rids)[i] = state->g.out.rids->rids[i].rid; + (*rids)[i] = state->rid_array->rids[i].rid; } done: |