diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-03-31 11:58:37 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-03-31 11:58:37 +1100 |
commit | 631e688c821b78d09d77f5940074800525c554aa (patch) | |
tree | 74473f1727ea0afa27d9c15e50e4638c4d8faf28 | |
parent | 13be4d7ff42bd2b8bf5702a499c482404e5cd164 (diff) | |
parent | 4b8e4ea7286f045effb6feb4c7bf8c5ef4ed2f9b (diff) | |
download | samba-631e688c821b78d09d77f5940074800525c554aa.tar.gz samba-631e688c821b78d09d77f5940074800525c554aa.tar.bz2 samba-631e688c821b78d09d77f5940074800525c554aa.zip |
Merge branch 'master' into wspp-schema
149 files changed, 6737 insertions, 2871 deletions
diff --git a/docs-xml/manpages-3/vfs_dirsort.8.xml b/docs-xml/manpages-3/vfs_dirsort.8.xml new file mode 100644 index 0000000000..cec5f270c8 --- /dev/null +++ b/docs-xml/manpages-3/vfs_dirsort.8.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!DOCTYPE refentry PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> +<refentry id="vfs_dirsort.8"> + +<refmeta> + <refentrytitle>vfs_dirsort</refentrytitle> + <manvolnum>8</manvolnum> + <refmiscinfo class="source">Samba</refmiscinfo> + <refmiscinfo class="manual">System Administration tools</refmiscinfo> + <refmiscinfo class="version">3.3</refmiscinfo> +</refmeta> + + +<refnamediv> + <refname>vfs_dirsort</refname> + <refpurpose>Sort directory contents</refpurpose> +</refnamediv> + +<refsynopsisdiv> + <cmdsynopsis> + <command>vfs objects = dirsort</command> + </cmdsynopsis> +</refsynopsisdiv> + +<refsect1> + <title>DESCRIPTION</title> + + <para>This VFS module is part of the + <citerefentry><refentrytitle>samba</refentrytitle> + <manvolnum>7</manvolnum></citerefentry> suite.</para> + + <para>The <command>vfs_dirsort</command> module sorts directory + entries alphabetically before sending them to the client.</para> + + <para>Please be aware that adding this module might have negative + performance implications for large directories.</para> + +</refsect1> + +<refsect1> + <title>EXAMPLES</title> + + <para>Sort directories for all shares:</para> + +<programlisting> + <smbconfsection name="[global]"/> + <smbconfoption name="vfs objects">dirsort</smbconfoption> +</programlisting> + +</refsect1> + +<refsect1> + <title>VERSION</title> + + <para>This man page is correct for version 3.3 of the Samba suite. + </para> +</refsect1> + +<refsect1> + <title>AUTHOR</title> + + <para>The original Samba software and related utilities + were created by Andrew Tridgell. Samba is now developed + by the Samba Team as an Open Source project similar + to the way the Linux kernel is developed.</para> + +</refsect1> + +</refentry> diff --git a/examples/libsmbclient/testbrowse.c b/examples/libsmbclient/testbrowse.c index a6e6395078..c3fb3946da 100644 --- a/examples/libsmbclient/testbrowse.c +++ b/examples/libsmbclient/testbrowse.c @@ -197,7 +197,7 @@ get_auth_data_with_context_fn(SMBCCTX * context, char * pPassword, int maxLenPassword) { - printf("Authenticating with context 0x%lx", context); + printf("Authenticating with context %p", context); if (context != NULL) { char *user_data = smbc_getOptionUserData(context); printf(" with user data %s", user_data); diff --git a/examples/libsmbclient/testfstatvfs.c b/examples/libsmbclient/testfstatvfs.c index b4dafefff6..73f42d446a 100644 --- a/examples/libsmbclient/testfstatvfs.c +++ b/examples/libsmbclient/testfstatvfs.c @@ -75,13 +75,20 @@ int main(int argc, char * argv[]) printf("\n"); printf("Block Size: %lu\n", statvfsbuf.f_bsize); printf("Fragment Size: %lu\n", statvfsbuf.f_frsize); - printf("Blocks: %llu\n", statvfsbuf.f_blocks); - printf("Free Blocks: %llu\n", statvfsbuf.f_bfree); - printf("Available Blocks: %llu\n", statvfsbuf.f_bavail); - printf("Files : %llu\n", statvfsbuf.f_files); - printf("Free Files: %llu\n", statvfsbuf.f_ffree); - printf("Available Files: %llu\n", statvfsbuf.f_favail); - printf("File System ID: %lu\n", statvfsbuf.f_fsid); + printf("Blocks: %llu\n", + (unsigned long long) statvfsbuf.f_blocks); + printf("Free Blocks: %llu\n", + (unsigned long long) statvfsbuf.f_bfree); + printf("Available Blocks: %llu\n", + (unsigned long long) statvfsbuf.f_bavail); + printf("Files : %llu\n", + (unsigned long long) statvfsbuf.f_files); + printf("Free Files: %llu\n", + (unsigned long long) statvfsbuf.f_ffree); + printf("Available Files: %llu\n", + (unsigned long long) statvfsbuf.f_favail); + printf("File System ID: %lu\n", + (unsigned long) statvfsbuf.f_fsid); printf("\n"); printf("Flags: 0x%lx\n", statvfsbuf.f_flag); diff --git a/examples/libsmbclient/testsmbc.c b/examples/libsmbclient/testsmbc.c index 1f06437293..de42428c2b 100644 --- a/examples/libsmbclient/testsmbc.c +++ b/examples/libsmbclient/testsmbc.c @@ -21,6 +21,7 @@ #include <stdio.h> #include <errno.h> +#include <time.h> #include <sys/time.h> #include <string.h> #include <unistd.h> @@ -33,8 +34,12 @@ int global_id = 0; void print_list_fn(struct print_job_info *pji) { - fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %u, User: %s, Name: %s\n", - pji->id, pji->priority, pji->size, pji->user, pji->name); + fprintf(stdout, "Print job: ID: %u, Prio: %u, Size: %lu, User: %s, Name: %s\n", + pji->id, + pji->priority, + (unsigned long) pji->size, + pji->user, + pji->name); global_id = pji->id; @@ -137,7 +142,8 @@ int main(int argc, char *argv[]) } - fprintf(stdout, "Wrote %d bytes to file: %s\n", sizeof(buff), buff); + fprintf(stdout, "Wrote %lu bytes to file: %s\n", + (unsigned long) sizeof(buff), buff); /* Now, seek the file back to offset 0 */ diff --git a/examples/libsmbclient/teststatvfs.c b/examples/libsmbclient/teststatvfs.c index 8812002d5c..b7e6b5159e 100644 --- a/examples/libsmbclient/teststatvfs.c +++ b/examples/libsmbclient/teststatvfs.c @@ -49,13 +49,20 @@ int main(int argc, char * argv[]) printf("\n"); printf("Block Size: %lu\n", statvfsbuf.f_bsize); printf("Fragment Size: %lu\n", statvfsbuf.f_frsize); - printf("Blocks: %llu\n", statvfsbuf.f_blocks); - printf("Free Blocks: %llu\n", statvfsbuf.f_bfree); - printf("Available Blocks: %llu\n", statvfsbuf.f_bavail); - printf("Files : %llu\n", statvfsbuf.f_files); - printf("Free Files: %llu\n", statvfsbuf.f_ffree); - printf("Available Files: %llu\n", statvfsbuf.f_favail); - printf("File System ID: %lu\n", statvfsbuf.f_fsid); + printf("Blocks: %llu\n", + (unsigned long long) statvfsbuf.f_blocks); + printf("Free Blocks: %llu\n", + (unsigned long long) statvfsbuf.f_bfree); + printf("Available Blocks: %llu\n", + (unsigned long long) statvfsbuf.f_bavail); + printf("Files : %llu\n", + (unsigned long long) statvfsbuf.f_files); + printf("Free Files: %llu\n", + (unsigned long long) statvfsbuf.f_ffree); + printf("Available Files: %llu\n", + (unsigned long long) statvfsbuf.f_favail); + printf("File System ID: %lu\n", + (unsigned long) statvfsbuf.f_fsid); printf("\n"); printf("Flags: 0x%lx\n", statvfsbuf.f_flag); diff --git a/lib/replace/libreplace_network.m4 b/lib/replace/libreplace_network.m4 index 3bac72d136..2af02312ab 100644 --- a/lib/replace/libreplace_network.m4 +++ b/lib/replace/libreplace_network.m4 @@ -170,7 +170,7 @@ fi # The following tests need LIBS="${LIBREPLACE_NETWORK_LIBS}" old_LIBS=$LIBS LIBS="${LIBREPLACE_NETWORK_LIBS}" -SAVE_CPPFLAGS="$CPPFLAGS" +libreplace_SAVE_CPPFLAGS="$CPPFLAGS" CPPFLAGS="$CPPFLAGS -I$libreplacedir" AC_CHECK_FUNCS(socketpair,[],[LIBREPLACE_NETWORK_OBJS="${LIBREPLACE_NETWORK_OBJS} socketpair.o"]) @@ -381,7 +381,7 @@ if test x"$libreplace_cv_HAVE_IPV6" = x"yes"; then fi LIBS=$old_LIBS -CPPFLAGS="$SAVE_CPPFLAGS" +CPPFLAGS="$libreplace_SAVE_CPPFLAGS" LIBREPLACEOBJ="${LIBREPLACEOBJ} ${LIBREPLACE_NETWORK_OBJS}" diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index 44082e78a1..553827b192 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -218,6 +218,7 @@ struct socket_info int bcast; int is_server; int connected; + int defer_connect; char *path; char *tmp_path; @@ -1686,10 +1687,15 @@ _PUBLIC_ int swrap_connect(int s, const struct sockaddr *serv_addr, socklen_t ad ret = sockaddr_convert_to_un(si, (const struct sockaddr *)serv_addr, addrlen, &un_addr, 0, NULL); if (ret == -1) return -1; - swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); + if (si->type == SOCK_DGRAM) { + si->defer_connect = 1; + ret = 0; + } else { + swrap_dump_packet(si, serv_addr, SWRAP_CONNECT_SEND, NULL, 0); - ret = real_connect(s, (struct sockaddr *)&un_addr, - sizeof(struct sockaddr_un)); + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(struct sockaddr_un)); + } /* to give better errors */ if (ret == -1 && errno == ENOENT) { @@ -1917,7 +1923,22 @@ _PUBLIC_ ssize_t swrap_sendto(int s, const void *buf, size_t len, int flags, con return len; } - + + if (si->defer_connect) { + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(un_addr)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + return ret; + } + si->defer_connect = 0; + } + ret = real_sendto(s, buf, len, flags, (struct sockaddr *)&un_addr, sizeof(un_addr)); break; default: @@ -2002,6 +2023,33 @@ _PUBLIC_ ssize_t swrap_send(int s, const void *buf, size_t len, int flags) len = MIN(len, 1500); + if (si->defer_connect) { + struct sockaddr_un un_addr; + int bcast = 0; + + if (si->bound == 0) { + ret = swrap_auto_bind(si, si->family); + if (ret == -1) return -1; + } + + ret = sockaddr_convert_to_un(si, si->peername, si->peername_len, + &un_addr, 0, &bcast); + if (ret == -1) return -1; + + ret = real_connect(s, (struct sockaddr *)&un_addr, + sizeof(un_addr)); + + /* to give better errors */ + if (ret == -1 && errno == ENOENT) { + errno = EHOSTUNREACH; + } + + if (ret == -1) { + return ret; + } + si->defer_connect = 0; + } + ret = real_send(s, buf, len, flags); if (ret == -1) { diff --git a/lib/talloc/talloc.h b/lib/talloc/talloc.h index 5c8d5c5fe2..f87564a13b 100644 --- a/lib/talloc/talloc.h +++ b/lib/talloc/talloc.h @@ -94,7 +94,7 @@ typedef void TALLOC_CTX; #define talloc_array(ctx, type, count) (type *)_talloc_array(ctx, sizeof(type), count, #type) #define talloc_array_size(ctx, size, count) _talloc_array(ctx, size, count, __location__) #define talloc_array_ptrtype(ctx, ptr, count) (_TALLOC_TYPEOF(ptr))talloc_array_size(ctx, sizeof(*(ptr)), count) -#define talloc_array_length(ctx) ((ctx) ? talloc_get_size(ctx)/sizeof(*ctx) : 0) +#define talloc_array_length(ctx) (talloc_get_size(ctx)/sizeof(*ctx)) #define talloc_realloc(ctx, p, type, count) (type *)_talloc_realloc_array(ctx, p, sizeof(type), count, #type) #define talloc_realloc_size(ctx, ptr, size) _talloc_realloc(ctx, ptr, size, __location__) diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 2811882fed..3d13dfd47d 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -44,11 +44,11 @@ struct tsocket_address_bsd { bool broadcast; union { struct sockaddr sa; - struct sockaddr_in sin; + struct sockaddr_in in; #ifdef HAVE_IPV6 - struct sockaddr_in6 sin6; + struct sockaddr_in6 in6; #endif - struct sockaddr_un sun; + struct sockaddr_un un; struct sockaddr_storage ss; } u; }; @@ -204,14 +204,14 @@ char *tsocket_address_inet_addr_string(const struct tsocket_address *addr, switch (bsda->u.sa.sa_family) { case AF_INET: - str = inet_ntop(bsda->u.sin.sin_family, - &bsda->u.sin.sin_addr, + str = inet_ntop(bsda->u.in.sin_family, + &bsda->u.in.sin_addr, addr_str, sizeof(addr_str)); break; #ifdef HAVE_IPV6 case AF_INET6: - str = inet_ntop(bsda->u.sin6.sin6_family, - &bsda->u.sin6.sin6_addr, + str = inet_ntop(bsda->u.in6.sin6_family, + &bsda->u.in6.sin6_addr, addr_str, sizeof(addr_str)); break; #endif @@ -240,11 +240,11 @@ uint16_t tsocket_address_inet_port(const struct tsocket_address *addr) switch (bsda->u.sa.sa_family) { case AF_INET: - port = ntohs(bsda->u.sin.sin_port); + port = ntohs(bsda->u.in.sin_port); break; #ifdef HAVE_IPV6 case AF_INET6: - port = ntohs(bsda->u.sin6.sin6_port); + port = ntohs(bsda->u.in6.sin6_port); break; #endif default: @@ -268,11 +268,11 @@ int tsocket_address_inet_set_port(struct tsocket_address *addr, switch (bsda->u.sa.sa_family) { case AF_INET: - bsda->u.sin.sin_port = htons(port); + bsda->u.in.sin_port = htons(port); break; #ifdef HAVE_IPV6 case AF_INET6: - bsda->u.sin6.sin6_port = htons(port); + bsda->u.in6.sin6_port = htons(port); break; #endif default: @@ -301,21 +301,21 @@ int _tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx, struct tsocket_address **_addr, const char *location) { - struct sockaddr_un sun; - void *p = &sun; + struct sockaddr_un un; + void *p = &un; int ret; if (!path) { path = ""; } - ZERO_STRUCT(sun); - sun.sun_family = AF_UNIX; - strncpy(sun.sun_path, path, sizeof(sun.sun_path)); + ZERO_STRUCT(un); + un.sun_family = AF_UNIX; + strncpy(un.sun_path, path, sizeof(un.sun_path)); ret = _tsocket_address_bsd_from_sockaddr(mem_ctx, (struct sockaddr *)p, - sizeof(sun), + sizeof(un), _addr, location); @@ -336,7 +336,7 @@ char *tsocket_address_unix_path(const struct tsocket_address *addr, switch (bsda->u.sa.sa_family) { case AF_UNIX: - str = bsda->u.sun.sun_path; + str = bsda->u.un.sun_path; break; default: errno = EINVAL; @@ -359,7 +359,7 @@ static char *tsocket_address_bsd_string(const struct tsocket_address *addr, switch (bsda->u.sa.sa_family) { case AF_UNIX: return talloc_asprintf(mem_ctx, "unix:%s", - bsda->u.sun.sun_path); + bsda->u.un.sun_path); case AF_INET: prefix = "ipv4"; break; @@ -469,27 +469,27 @@ static int tsocket_address_bsd_create_socket(const struct tsocket_address *addr, errno = EINVAL; return -1; } - if (bsda->u.sun.sun_path[0] != 0) { + if (bsda->u.un.sun_path[0] != 0) { do_bind = true; } break; case AF_INET: - if (bsda->u.sin.sin_port != 0) { + if (bsda->u.in.sin_port != 0) { do_reuseaddr = true; do_bind = true; } - if (bsda->u.sin.sin_addr.s_addr == INADDR_ANY) { + if (bsda->u.in.sin_addr.s_addr == INADDR_ANY) { do_bind = true; } break; #ifdef HAVE_IPV6 case AF_INET6: - if (bsda->u.sin6.sin6_port != 0) { + if (bsda->u.in6.sin6_port != 0) { do_reuseaddr = true; do_bind = true; } if (memcmp(&in6addr_any, - &bsda->u.sin6.sin6_addr, + &bsda->u.in6.sin6_addr, sizeof(in6addr_any)) != 0) { do_bind = true; } diff --git a/lib/util/fault.m4 b/lib/util/fault.m4 index bac553a158..c22976998e 100644 --- a/lib/util/fault.m4 +++ b/lib/util/fault.m4 @@ -9,6 +9,8 @@ if test x"$ac_cv_header_execinfo_h" = x"yes" -a x"$ac_cv_func_ext_backtrace" = x EXECINFO_CPPFLAGS="$CPPFLAGS" EXECINFO_LDFLAGS="$LDFLAGS" LIB_REMOVE_USR_LIB(EXECINFO_LDFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(EXECINFO_CFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(EXECINFO_CPPFLAGS) else SMB_ENABLE(EXECINFO,NO) fi diff --git a/lib/util/tevent_ntstatus.c b/lib/util/tevent_ntstatus.c index 1a34e9c749..4e4339989a 100644 --- a/lib/util/tevent_ntstatus.c +++ b/lib/util/tevent_ntstatus.c @@ -49,3 +49,13 @@ bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *status) } return true; } + +NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req) +{ + NTSTATUS status; + + if (tevent_req_is_nterror(req, &status)) { + return status; + } + return NT_STATUS_OK; +} diff --git a/lib/util/tevent_ntstatus.h b/lib/util/tevent_ntstatus.h index 84c275fb13..d7194a9b73 100644 --- a/lib/util/tevent_ntstatus.h +++ b/lib/util/tevent_ntstatus.h @@ -28,5 +28,6 @@ bool tevent_req_nterror(struct tevent_req *req, NTSTATUS status); bool tevent_req_is_nterror(struct tevent_req *req, NTSTATUS *pstatus); +NTSTATUS tevent_req_simple_recv_ntstatus(struct tevent_req *req); #endif diff --git a/libcli/security/config.mk b/libcli/security/config.mk index 56d8e138ff..7ade01510c 100644 --- a/libcli/security/config.mk +++ b/libcli/security/config.mk @@ -2,4 +2,4 @@ PRIVATE_DEPENDENCIES = TALLOC LIBSECURITY_COMMON_OBJ_FILES = $(addprefix $(libclicommonsrcdir)/security/, \ - dom_sid.o) + dom_sid.o display_sec.o secace.o secacl.o) diff --git a/source3/lib/display_sec.c b/libcli/security/display_sec.c index fe1ae77edd..bec657da86 100644 --- a/source3/lib/display_sec.c +++ b/libcli/security/display_sec.c @@ -19,12 +19,16 @@ */ #include "includes.h" +#include "librpc/gen_ndr/security.h" +#include "libcli/security/secace.h" +#include "libcli/security/dom_sid.h" +#include "librpc/ndr/libndr.h" /**************************************************************************** convert a security permissions into a string ****************************************************************************/ -char *get_sec_mask_str(TALLOC_CTX *ctx, uint32 type) +char *get_sec_mask_str(TALLOC_CTX *ctx, uint32_t type) { char *typestr = talloc_strdup(ctx, ""); @@ -32,77 +36,77 @@ char *get_sec_mask_str(TALLOC_CTX *ctx, uint32 type) return NULL; } - if (type & GENERIC_ALL_ACCESS) { + if (type & SEC_GENERIC_ALL) { typestr = talloc_asprintf_append(typestr, "Generic all access "); if (!typestr) { return NULL; } } - if (type & GENERIC_EXECUTE_ACCESS) { + if (type & SEC_GENERIC_EXECUTE) { typestr = talloc_asprintf_append(typestr, "Generic execute access"); if (!typestr) { return NULL; } } - if (type & GENERIC_WRITE_ACCESS) { + if (type & SEC_GENERIC_WRITE) { typestr = talloc_asprintf_append(typestr, "Generic write access "); if (!typestr) { return NULL; } } - if (type & GENERIC_READ_ACCESS) { + if (type & SEC_GENERIC_READ) { typestr = talloc_asprintf_append(typestr, "Generic read access "); if (!typestr) { return NULL; } } - if (type & MAXIMUM_ALLOWED_ACCESS) { + if (type & SEC_FLAG_MAXIMUM_ALLOWED) { typestr = talloc_asprintf_append(typestr, "MAXIMUM_ALLOWED_ACCESS "); if (!typestr) { return NULL; } } - if (type & SYSTEM_SECURITY_ACCESS) { + if (type & SEC_FLAG_SYSTEM_SECURITY) { typestr = talloc_asprintf_append(typestr, "SYSTEM_SECURITY_ACCESS "); if (!typestr) { return NULL; } } - if (type & SYNCHRONIZE_ACCESS) { + if (type & SEC_STD_SYNCHRONIZE) { typestr = talloc_asprintf_append(typestr, "SYNCHRONIZE_ACCESS "); if (!typestr) { return NULL; } } - if (type & WRITE_OWNER_ACCESS) { + if (type & SEC_STD_WRITE_OWNER) { typestr = talloc_asprintf_append(typestr, "WRITE_OWNER_ACCESS "); if (!typestr) { return NULL; } } - if (type & WRITE_DAC_ACCESS) { + if (type & SEC_STD_WRITE_DAC) { typestr = talloc_asprintf_append(typestr, "WRITE_DAC_ACCESS "); if (!typestr) { return NULL; } } - if (type & READ_CONTROL_ACCESS) { + if (type & SEC_STD_READ_CONTROL) { typestr = talloc_asprintf_append(typestr, "READ_CONTROL_ACCESS "); if (!typestr) { return NULL; } } - if (type & DELETE_ACCESS) { + if (type & SEC_STD_DELETE) { typestr = talloc_asprintf_append(typestr, "DELETE_ACCESS "); if (!typestr) { @@ -110,7 +114,7 @@ char *get_sec_mask_str(TALLOC_CTX *ctx, uint32 type) } } - printf("\t\tSpecific bits: 0x%lx\n", (unsigned long)type&SPECIFIC_RIGHTS_MASK); + printf("\t\tSpecific bits: 0x%lx\n", (unsigned long)type&SEC_MASK_SPECIFIC); return typestr; } @@ -122,7 +126,7 @@ void display_sec_access(uint32_t *info) { char *mask_str = get_sec_mask_str(NULL, *info); printf("\t\tPermissions: 0x%x: %s\n", *info, mask_str ? mask_str : ""); - TALLOC_FREE(mask_str); + talloc_free(mask_str); } /**************************************************************************** @@ -170,9 +174,9 @@ static void disp_sec_ace_object(struct security_ace_object *object) /**************************************************************************** display sec_ace structure ****************************************************************************/ -void display_sec_ace(SEC_ACE *ace) +void display_sec_ace(struct security_ace *ace) { - fstring sid_str; + char *sid_str; printf("\tACE\n\t\ttype: "); switch (ace->type) { @@ -211,8 +215,9 @@ void display_sec_ace(SEC_ACE *ace) printf(" (%d) flags: 0x%02x ", ace->type, ace->flags); display_sec_ace_flags(ace->flags); display_sec_access(&ace->access_mask); - sid_to_fstring(sid_str, &ace->trustee); + sid_str = dom_sid_string(NULL, &ace->trustee); printf("\t\tSID: %s\n\n", sid_str); + talloc_free(sid_str); if (sec_ace_object(ace->type)) { disp_sec_ace_object(&ace->object.object); @@ -223,7 +228,7 @@ void display_sec_ace(SEC_ACE *ace) /**************************************************************************** display sec_acl structure ****************************************************************************/ -void display_sec_acl(SEC_ACL *sec_acl) +void display_sec_acl(struct security_acl *sec_acl) { int i; @@ -238,54 +243,52 @@ void display_sec_acl(SEC_ACL *sec_acl) } } -void display_acl_type(uint16 type) +void display_acl_type(uint16_t type) { - fstring typestr=""; - - typestr[0] = 0; + printf("type: 0x%04x: ", type); if (type & SEC_DESC_OWNER_DEFAULTED) /* 0x0001 */ - fstrcat(typestr, "SEC_DESC_OWNER_DEFAULTED "); + printf("SEC_DESC_OWNER_DEFAULTED "); if (type & SEC_DESC_GROUP_DEFAULTED) /* 0x0002 */ - fstrcat(typestr, "SEC_DESC_GROUP_DEFAULTED "); + printf("SEC_DESC_GROUP_DEFAULTED "); if (type & SEC_DESC_DACL_PRESENT) /* 0x0004 */ - fstrcat(typestr, "SEC_DESC_DACL_PRESENT "); + printf("SEC_DESC_DACL_PRESENT "); if (type & SEC_DESC_DACL_DEFAULTED) /* 0x0008 */ - fstrcat(typestr, "SEC_DESC_DACL_DEFAULTED "); + printf("SEC_DESC_DACL_DEFAULTED "); if (type & SEC_DESC_SACL_PRESENT) /* 0x0010 */ - fstrcat(typestr, "SEC_DESC_SACL_PRESENT "); + printf("SEC_DESC_SACL_PRESENT "); if (type & SEC_DESC_SACL_DEFAULTED) /* 0x0020 */ - fstrcat(typestr, "SEC_DESC_SACL_DEFAULTED "); + printf("SEC_DESC_SACL_DEFAULTED "); if (type & SEC_DESC_DACL_TRUSTED) /* 0x0040 */ - fstrcat(typestr, "SEC_DESC_DACL_TRUSTED "); + printf("SEC_DESC_DACL_TRUSTED "); if (type & SEC_DESC_SERVER_SECURITY) /* 0x0080 */ - fstrcat(typestr, "SEC_DESC_SERVER_SECURITY "); + printf("SEC_DESC_SERVER_SECURITY "); if (type & SEC_DESC_DACL_AUTO_INHERIT_REQ) /* 0x0100 */ - fstrcat(typestr, "SEC_DESC_DACL_AUTO_INHERIT_REQ "); + printf("SEC_DESC_DACL_AUTO_INHERIT_REQ "); if (type & SEC_DESC_SACL_AUTO_INHERIT_REQ) /* 0x0200 */ - fstrcat(typestr, "SEC_DESC_SACL_AUTO_INHERIT_REQ "); + printf("SEC_DESC_SACL_AUTO_INHERIT_REQ "); if (type & SEC_DESC_DACL_AUTO_INHERITED) /* 0x0400 */ - fstrcat(typestr, "SEC_DESC_DACL_AUTO_INHERITED "); + printf("SEC_DESC_DACL_AUTO_INHERITED "); if (type & SEC_DESC_SACL_AUTO_INHERITED) /* 0x0800 */ - fstrcat(typestr, "SEC_DESC_SACL_AUTO_INHERITED "); + printf("SEC_DESC_SACL_AUTO_INHERITED "); if (type & SEC_DESC_DACL_PROTECTED) /* 0x1000 */ - fstrcat(typestr, "SEC_DESC_DACL_PROTECTED "); + printf("SEC_DESC_DACL_PROTECTED "); if (type & SEC_DESC_SACL_PROTECTED) /* 0x2000 */ - fstrcat(typestr, "SEC_DESC_SACL_PROTECTED "); + printf("SEC_DESC_SACL_PROTECTED "); if (type & SEC_DESC_RM_CONTROL_VALID) /* 0x4000 */ - fstrcat(typestr, "SEC_DESC_RM_CONTROL_VALID "); + printf("SEC_DESC_RM_CONTROL_VALID "); if (type & SEC_DESC_SELF_RELATIVE) /* 0x8000 */ - fstrcat(typestr, "SEC_DESC_SELF_RELATIVE "); + printf("SEC_DESC_SELF_RELATIVE "); - printf("type: 0x%04x: %s\n", type, typestr); + printf("\n"); } /**************************************************************************** display sec_desc structure ****************************************************************************/ -void display_sec_desc(SEC_DESC *sec) +void display_sec_desc(struct security_descriptor *sec) { - fstring sid_str; + char *sid_str; if (!sec) { printf("NULL\n"); @@ -306,12 +309,14 @@ void display_sec_desc(SEC_DESC *sec) } if (sec->owner_sid) { - sid_to_fstring(sid_str, sec->owner_sid); + sid_str = dom_sid_string(NULL, sec->owner_sid); printf("\tOwner SID:\t%s\n", sid_str); + talloc_free(sid_str); } if (sec->group_sid) { - sid_to_fstring(sid_str, sec->group_sid); + sid_str = dom_sid_string(NULL, sec->group_sid); printf("\tGroup SID:\t%s\n", sid_str); + talloc_free(sid_str); } } diff --git a/libcli/util/doserr.c b/libcli/util/doserr.c index 5104c3ee02..1a7422e3f6 100644 --- a/libcli/util/doserr.c +++ b/libcli/util/doserr.c @@ -124,6 +124,7 @@ static const struct werror_code_struct dos_errs[] = { "WERR_DS_DRA_DB_ERROR", WERR_DS_DRA_DB_ERROR }, { "WERR_DS_DRA_NO_REPLICA", WERR_DS_DRA_NO_REPLICA }, { "WERR_DS_DRA_ACCESS_DENIED", WERR_DS_DRA_ACCESS_DENIED }, + { "WERR_DS_DRA_SOURCE_DISABLED", WERR_DS_DRA_SOURCE_DISABLED }, { "WERR_DS_DNS_LOOKUP_FAILURE", WERR_DS_DNS_LOOKUP_FAILURE }, { "WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX", WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX }, { "WERR_DS_NO_MSDS_INTID", WERR_DS_NO_MSDS_INTID }, diff --git a/libcli/util/werror.h b/libcli/util/werror.h index d92232706a..a69587f361 100644 --- a/libcli/util/werror.h +++ b/libcli/util/werror.h @@ -248,6 +248,7 @@ typedef uint32_t WERROR; #define WERR_DS_DRA_DB_ERROR W_ERROR(0x00002103) #define WERR_DS_DRA_NO_REPLICA W_ERROR(0x00002104) #define WERR_DS_DRA_ACCESS_DENIED W_ERROR(0x00002105) +#define WERR_DS_DRA_SOURCE_DISABLED W_ERROR(0x00002108) #define WERR_DS_DNS_LOOKUP_FAILURE W_ERROR(0x0000214c) #define WERR_DS_WRONG_LINKED_ATTRIBUTE_SYNTAX W_ERROR(0x00002150) #define WERR_DS_NO_MSDS_INTID W_ERROR(0x00002194) diff --git a/librpc/gen_ndr/dcerpc.h b/librpc/gen_ndr/dcerpc.h new file mode 100644 index 0000000000..78834f6d28 --- /dev/null +++ b/librpc/gen_ndr/dcerpc.h @@ -0,0 +1,343 @@ +/* header auto-generated by pidl */ + +#include <stdint.h> + +#include "libcli/util/ntstatus.h" + +#include "librpc/gen_ndr/misc.h" +#ifndef _HEADER_dcerpc +#define _HEADER_dcerpc + +#define DCERPC_REQUEST_LENGTH ( 24 ) +#define DCERPC_BIND_REASON_ASYNTAX ( 1 ) +#define DCERPC_BIND_PROVIDER_REJECT ( 2 ) +#define DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED ( 4 ) +#define DCERPC_BIND_REASON_INVALID_AUTH_TYPE ( 8 ) +#define DCERPC_RESPONSE_LENGTH ( 24 ) +#define DCERPC_FAULT_OP_RNG_ERROR ( 0x1c010002 ) +#define DCERPC_FAULT_UNK_IF ( 0x1c010003 ) +#define DCERPC_FAULT_NDR ( 0x000006f7 ) +#define DCERPC_FAULT_INVALID_TAG ( 0x1c000006 ) +#define DCERPC_FAULT_CONTEXT_MISMATCH ( 0x1c00001a ) +#define DCERPC_FAULT_OTHER ( 0x00000001 ) +#define DCERPC_FAULT_ACCESS_DENIED ( 0x00000005 ) +#define DCERPC_FAULT_CANT_PERFORM ( 0x000006d8 ) +#define DCERPC_FAULT_TODO ( 0x00000042 ) +#define DCERPC_AUTH_LEVEL_DEFAULT ( DCERPC_AUTH_LEVEL_CONNECT ) +#define DCERPC_AUTH_TRAILER_LENGTH ( 8 ) +#define DCERPC_PFC_FLAG_FIRST ( 0x01 ) +#define DCERPC_PFC_FLAG_LAST ( 0x02 ) +#define DCERPC_PFC_FLAG_PENDING_CANCEL ( 0x04 ) +#define DCERPC_PFC_FLAG_SUPPORT_HEADER_SIGN ( DCERPC_PFC_FLAG_PENDING_CANCEL ) +#define DCERPC_PFC_FLAG_CONC_MPX ( 0x10 ) +#define DCERPC_PFC_FLAG_DID_NOT_EXECUTE ( 0x20 ) +#define DCERPC_PFC_FLAG_MAYBE ( 0x40 ) +#define DCERPC_PFC_FLAG_OBJECT_UUID ( 0x80 ) +#define DCERPC_PFC_OFFSET ( 3 ) +#define DCERPC_DREP_OFFSET ( 4 ) +#define DCERPC_FRAG_LEN_OFFSET ( 8 ) +#define DCERPC_AUTH_LEN_OFFSET ( 10 ) +#define DCERPC_DREP_LE ( 0x10 ) +struct dcerpc_ctx_list { + uint16_t context_id; + uint8_t num_transfer_syntaxes; + struct ndr_syntax_id abstract_syntax; + struct ndr_syntax_id *transfer_syntaxes; +}; + +struct dcerpc_bind { + uint16_t max_xmit_frag; + uint16_t max_recv_frag; + uint32_t assoc_group_id; + uint8_t num_contexts; + struct dcerpc_ctx_list *ctx_list; + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN4)] */ + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_empty { + char _empty_; +}; + +union dcerpc_object { + struct dcerpc_empty empty;/* [default] */ + struct GUID object;/* [case(LIBNDR_FLAG_OBJECT_PRESENT)] */ +}/* [nodiscriminant] */; + +struct dcerpc_request { + uint32_t alloc_hint; + uint16_t context_id; + uint16_t opnum; + union dcerpc_object object;/* [switch_is(ndr->flags&LIBNDR_FLAG_OBJECT_PRESENT)] */ + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN8)] */ + DATA_BLOB stub_and_verifier;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_ack_ctx { + uint16_t result; + uint16_t reason; + struct ndr_syntax_id syntax; +}; + +struct dcerpc_bind_ack { + uint16_t max_xmit_frag; + uint16_t max_recv_frag; + uint32_t assoc_group_id; + uint16_t secondary_address_size;/* [value(strlen(secondary_address)+1)] */ + const char *secondary_address;/* [charset(DOS)] */ + DATA_BLOB _pad1;/* [flag(LIBNDR_FLAG_ALIGN4)] */ + uint8_t num_results; + struct dcerpc_ack_ctx *ctx_list; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_bind_nak_versions { + uint32_t num_versions; + uint32_t *versions; +}; + +union dcerpc_bind_nak_versions_ctr { + struct dcerpc_bind_nak_versions v;/* [case(DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED)] */ +}/* [nodiscriminant] */; + +struct dcerpc_bind_nak { + uint16_t reject_reason; + union dcerpc_bind_nak_versions_ctr versions;/* [switch_is(reject_reason)] */ +}; + +struct dcerpc_response { + uint32_t alloc_hint; + uint16_t context_id; + uint8_t cancel_count; + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_ALIGN8)] */ + DATA_BLOB stub_and_verifier;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +struct dcerpc_fault { + uint32_t alloc_hint; + uint16_t context_id; + uint8_t cancel_count; + uint32_t status; + DATA_BLOB _pad;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}; + +enum dcerpc_AuthType +#ifndef USE_UINT_ENUMS + { + DCERPC_AUTH_TYPE_NONE=0, + DCERPC_AUTH_TYPE_KRB5_1=1, + DCERPC_AUTH_TYPE_SPNEGO=9, + DCERPC_AUTH_TYPE_NTLMSSP=10, + DCERPC_AUTH_TYPE_KRB5=16, + DCERPC_AUTH_TYPE_DPA=17, + DCERPC_AUTH_TYPE_MSN=18, + DCERPC_AUTH_TYPE_DIGEST=21, + DCERPC_AUTH_TYPE_SCHANNEL=68, + DCERPC_AUTH_TYPE_MSMQ=100 +} +#else + { __donnot_use_enum_dcerpc_AuthType=0x7FFFFFFF} +#define DCERPC_AUTH_TYPE_NONE ( 0 ) +#define DCERPC_AUTH_TYPE_KRB5_1 ( 1 ) +#define DCERPC_AUTH_TYPE_SPNEGO ( 9 ) +#define DCERPC_AUTH_TYPE_NTLMSSP ( 10 ) +#define DCERPC_AUTH_TYPE_KRB5 ( 16 ) +#define DCERPC_AUTH_TYPE_DPA ( 17 ) +#define DCERPC_AUTH_TYPE_MSN ( 18 ) +#define DCERPC_AUTH_TYPE_DIGEST ( 21 ) +#define DCERPC_AUTH_TYPE_SCHANNEL ( 68 ) +#define DCERPC_AUTH_TYPE_MSMQ ( 100 ) +#endif +; + +enum dcerpc_AuthLevel +#ifndef USE_UINT_ENUMS + { + DCERPC_AUTH_LEVEL_NONE=1, + DCERPC_AUTH_LEVEL_CONNECT=2, + DCERPC_AUTH_LEVEL_CALL=3, + DCERPC_AUTH_LEVEL_PACKET=4, + DCERPC_AUTH_LEVEL_INTEGRITY=5, + DCERPC_AUTH_LEVEL_PRIVACY=6 +} +#else + { __donnot_use_enum_dcerpc_AuthLevel=0x7FFFFFFF} +#define DCERPC_AUTH_LEVEL_NONE ( 1 ) +#define DCERPC_AUTH_LEVEL_CONNECT ( 2 ) +#define DCERPC_AUTH_LEVEL_CALL ( 3 ) +#define DCERPC_AUTH_LEVEL_PACKET ( 4 ) +#define DCERPC_AUTH_LEVEL_INTEGRITY ( 5 ) +#define DCERPC_AUTH_LEVEL_PRIVACY ( 6 ) +#endif +; + +struct dcerpc_auth { + enum dcerpc_AuthType auth_type; + enum dcerpc_AuthLevel auth_level; + uint8_t auth_pad_length; + uint8_t auth_reserved; + uint32_t auth_context_id; + DATA_BLOB credentials;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_auth3 { + uint32_t _pad; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_orphaned { + uint32_t _pad; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_co_cancel { + uint32_t _pad; + DATA_BLOB auth_info;/* [flag(LIBNDR_FLAG_REMAINING)] */ +}/* [public] */; + +struct dcerpc_cl_cancel { + uint32_t version; + uint32_t id; +}/* [public] */; + +struct dcerpc_cancel_ack { + uint32_t version; + uint32_t id; + uint32_t server_is_accepting; +}/* [public] */; + +struct dcerpc_fack { + uint32_t version; + uint8_t _pad1; + uint16_t window_size; + uint32_t max_tdsu; + uint32_t max_frag_size; + uint16_t serial_no; + uint16_t selack_size; + uint32_t *selack; +}/* [public] */; + +struct dcerpc_ack { + char _empty_; +}/* [public] */; + +struct dcerpc_ping { + char _empty_; +}/* [public] */; + +struct dcerpc_shutdown { + char _empty_; +}/* [public] */; + +struct dcerpc_working { + char _empty_; +}/* [public] */; + +enum dcerpc_pkt_type +#ifndef USE_UINT_ENUMS + { + DCERPC_PKT_REQUEST=0, + DCERPC_PKT_PING=1, + DCERPC_PKT_RESPONSE=2, + DCERPC_PKT_FAULT=3, + DCERPC_PKT_WORKING=4, + DCERPC_PKT_NOCALL=5, + DCERPC_PKT_REJECT=6, + DCERPC_PKT_ACK=7, + DCERPC_PKT_CL_CANCEL=8, + DCERPC_PKT_FACK=9, + DCERPC_PKT_CANCEL_ACK=10, + DCERPC_PKT_BIND=11, + DCERPC_PKT_BIND_ACK=12, + DCERPC_PKT_BIND_NAK=13, + DCERPC_PKT_ALTER=14, + DCERPC_PKT_ALTER_RESP=15, + DCERPC_PKT_AUTH3=16, + DCERPC_PKT_SHUTDOWN=17, + DCERPC_PKT_CO_CANCEL=18, + DCERPC_PKT_ORPHANED=19 +} +#else + { __donnot_use_enum_dcerpc_pkt_type=0x7FFFFFFF} +#define DCERPC_PKT_REQUEST ( 0 ) +#define DCERPC_PKT_PING ( 1 ) +#define DCERPC_PKT_RESPONSE ( 2 ) +#define DCERPC_PKT_FAULT ( 3 ) +#define DCERPC_PKT_WORKING ( 4 ) +#define DCERPC_PKT_NOCALL ( 5 ) +#define DCERPC_PKT_REJECT ( 6 ) +#define DCERPC_PKT_ACK ( 7 ) +#define DCERPC_PKT_CL_CANCEL ( 8 ) +#define DCERPC_PKT_FACK ( 9 ) +#define DCERPC_PKT_CANCEL_ACK ( 10 ) +#define DCERPC_PKT_BIND ( 11 ) +#define DCERPC_PKT_BIND_ACK ( 12 ) +#define DCERPC_PKT_BIND_NAK ( 13 ) +#define DCERPC_PKT_ALTER ( 14 ) +#define DCERPC_PKT_ALTER_RESP ( 15 ) +#define DCERPC_PKT_AUTH3 ( 16 ) +#define DCERPC_PKT_SHUTDOWN ( 17 ) +#define DCERPC_PKT_CO_CANCEL ( 18 ) +#define DCERPC_PKT_ORPHANED ( 19 ) +#endif +; + +union dcerpc_payload { + struct dcerpc_request request;/* [case(DCERPC_PKT_REQUEST)] */ + struct dcerpc_ping ping;/* [case(DCERPC_PKT_PING)] */ + struct dcerpc_response response;/* [case(DCERPC_PKT_RESPONSE)] */ + struct dcerpc_fault fault;/* [case(DCERPC_PKT_FAULT)] */ + struct dcerpc_working working;/* [case(DCERPC_PKT_WORKING)] */ + struct dcerpc_fack nocall;/* [case(DCERPC_PKT_NOCALL)] */ + struct dcerpc_fault reject;/* [case(DCERPC_PKT_REJECT)] */ + struct dcerpc_ack ack;/* [case(DCERPC_PKT_ACK)] */ + struct dcerpc_cl_cancel cl_cancel;/* [case(DCERPC_PKT_CL_CANCEL)] */ + struct dcerpc_fack fack;/* [case(DCERPC_PKT_FACK)] */ + struct dcerpc_cancel_ack cancel_ack;/* [case(DCERPC_PKT_CANCEL_ACK)] */ + struct dcerpc_bind bind;/* [case(DCERPC_PKT_BIND)] */ + struct dcerpc_bind_ack bind_ack;/* [case(DCERPC_PKT_BIND_ACK)] */ + struct dcerpc_bind_nak bind_nak;/* [case(DCERPC_PKT_BIND_NAK)] */ + struct dcerpc_bind alter;/* [case(DCERPC_PKT_ALTER)] */ + struct dcerpc_bind_ack alter_resp;/* [case(DCERPC_PKT_ALTER_RESP)] */ + struct dcerpc_shutdown shutdown;/* [case(DCERPC_PKT_SHUTDOWN)] */ + struct dcerpc_co_cancel co_cancel;/* [case(DCERPC_PKT_CO_CANCEL)] */ + struct dcerpc_orphaned orphaned;/* [case(DCERPC_PKT_ORPHANED)] */ + struct dcerpc_auth3 auth3;/* [case(DCERPC_PKT_AUTH3)] */ +}/* [nodiscriminant] */; + +struct ncacn_packet { + uint8_t rpc_vers; + uint8_t rpc_vers_minor; + enum dcerpc_pkt_type ptype; + uint8_t pfc_flags; + uint8_t drep[4]; + uint16_t frag_length; + uint16_t auth_length; + uint32_t call_id; + union dcerpc_payload u;/* [switch_is(ptype)] */ +}/* [public] */; + +struct ncadg_packet { + uint8_t rpc_vers; + uint8_t ptype; + uint8_t pfc_flags; + uint8_t ncadg_flags; + uint8_t drep[3]; + uint8_t serial_high; + struct GUID object; + struct GUID iface; + struct GUID activity; + uint32_t server_boot; + uint32_t iface_version; + uint32_t seq_num; + uint16_t opnum; + uint16_t ihint; + uint16_t ahint; + uint16_t len; + uint16_t fragnum; + uint8_t auth_proto; + uint8_t serial_low; + union dcerpc_payload u;/* [switch_is(ptype)] */ +}/* [public] */; + +#endif /* _HEADER_dcerpc */ diff --git a/librpc/gen_ndr/ndr_dcerpc.c b/librpc/gen_ndr/ndr_dcerpc.c new file mode 100644 index 0000000000..c510967c7a --- /dev/null +++ b/librpc/gen_ndr/ndr_dcerpc.c @@ -0,0 +1,1834 @@ +/* parser auto-generated by pidl */ + +#include "includes.h" +#include "../librpc/gen_ndr/ndr_dcerpc.h" + +#include "librpc/gen_ndr/ndr_misc.h" +static enum ndr_err_code ndr_push_dcerpc_ctx_list(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ctx_list *r) +{ + uint32_t cntr_transfer_syntaxes_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->num_transfer_syntaxes)); + NDR_CHECK(ndr_push_ndr_syntax_id(ndr, NDR_SCALARS, &r->abstract_syntax)); + for (cntr_transfer_syntaxes_0 = 0; cntr_transfer_syntaxes_0 < r->num_transfer_syntaxes; cntr_transfer_syntaxes_0++) { + NDR_CHECK(ndr_push_ndr_syntax_id(ndr, NDR_SCALARS, &r->transfer_syntaxes[cntr_transfer_syntaxes_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_ctx_list(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ctx_list *r) +{ + uint32_t cntr_transfer_syntaxes_0; + TALLOC_CTX *_mem_save_transfer_syntaxes_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_transfer_syntaxes)); + NDR_CHECK(ndr_pull_ndr_syntax_id(ndr, NDR_SCALARS, &r->abstract_syntax)); + NDR_PULL_ALLOC_N(ndr, r->transfer_syntaxes, r->num_transfer_syntaxes); + _mem_save_transfer_syntaxes_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->transfer_syntaxes, 0); + for (cntr_transfer_syntaxes_0 = 0; cntr_transfer_syntaxes_0 < r->num_transfer_syntaxes; cntr_transfer_syntaxes_0++) { + NDR_CHECK(ndr_pull_ndr_syntax_id(ndr, NDR_SCALARS, &r->transfer_syntaxes[cntr_transfer_syntaxes_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_transfer_syntaxes_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ctx_list(struct ndr_print *ndr, const char *name, const struct dcerpc_ctx_list *r) +{ + uint32_t cntr_transfer_syntaxes_0; + ndr_print_struct(ndr, name, "dcerpc_ctx_list"); + ndr->depth++; + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint8(ndr, "num_transfer_syntaxes", r->num_transfer_syntaxes); + ndr_print_ndr_syntax_id(ndr, "abstract_syntax", &r->abstract_syntax); + ndr->print(ndr, "%s: ARRAY(%d)", "transfer_syntaxes", (int)r->num_transfer_syntaxes); + ndr->depth++; + for (cntr_transfer_syntaxes_0=0;cntr_transfer_syntaxes_0<r->num_transfer_syntaxes;cntr_transfer_syntaxes_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_transfer_syntaxes_0) != -1) { + ndr_print_ndr_syntax_id(ndr, "transfer_syntaxes", &r->transfer_syntaxes[cntr_transfer_syntaxes_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind *r) +{ + uint32_t cntr_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_xmit_frag)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_recv_frag)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->assoc_group_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->num_contexts)); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_contexts; cntr_ctx_list_0++) { + NDR_CHECK(ndr_push_dcerpc_ctx_list(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind *r) +{ + uint32_t cntr_ctx_list_0; + TALLOC_CTX *_mem_save_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_xmit_frag)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_recv_frag)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->assoc_group_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_contexts)); + NDR_PULL_ALLOC_N(ndr, r->ctx_list, r->num_contexts); + _mem_save_ctx_list_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->ctx_list, 0); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_contexts; cntr_ctx_list_0++) { + NDR_CHECK(ndr_pull_dcerpc_ctx_list(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ctx_list_0, 0); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind(struct ndr_print *ndr, const char *name, const struct dcerpc_bind *r) +{ + uint32_t cntr_ctx_list_0; + ndr_print_struct(ndr, name, "dcerpc_bind"); + ndr->depth++; + ndr_print_uint16(ndr, "max_xmit_frag", r->max_xmit_frag); + ndr_print_uint16(ndr, "max_recv_frag", r->max_recv_frag); + ndr_print_uint32(ndr, "assoc_group_id", r->assoc_group_id); + ndr_print_uint8(ndr, "num_contexts", r->num_contexts); + ndr->print(ndr, "%s: ARRAY(%d)", "ctx_list", (int)r->num_contexts); + ndr->depth++; + for (cntr_ctx_list_0=0;cntr_ctx_list_0<r->num_contexts;cntr_ctx_list_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_ctx_list_0) != -1) { + ndr_print_dcerpc_ctx_list(ndr, "ctx_list", &r->ctx_list[cntr_ctx_list_0]); + free(idx_0); + } + } + ndr->depth--; + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_empty(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_empty *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_empty(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_empty *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_empty(struct ndr_print *ndr, const char *name, const struct dcerpc_empty *r) +{ + ndr_print_struct(ndr, name, "dcerpc_empty"); + ndr->depth++; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_object(struct ndr_push *ndr, int ndr_flags, const union dcerpc_object *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + default: { + NDR_CHECK(ndr_push_dcerpc_empty(ndr, NDR_SCALARS, &r->empty)); + break; } + + case LIBNDR_FLAG_OBJECT_PRESENT: { + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->object)); + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + default: + break; + + case LIBNDR_FLAG_OBJECT_PRESENT: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_object(struct ndr_pull *ndr, int ndr_flags, union dcerpc_object *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + default: { + NDR_CHECK(ndr_pull_dcerpc_empty(ndr, NDR_SCALARS, &r->empty)); + break; } + + case LIBNDR_FLAG_OBJECT_PRESENT: { + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->object)); + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + default: + break; + + case LIBNDR_FLAG_OBJECT_PRESENT: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_object(struct ndr_print *ndr, const char *name, const union dcerpc_object *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "dcerpc_object"); + switch (level) { + default: + ndr_print_dcerpc_empty(ndr, "empty", &r->empty); + break; + + case LIBNDR_FLAG_OBJECT_PRESENT: + ndr_print_GUID(ndr, "object", &r->object); + break; + + } +} + +static enum ndr_err_code ndr_push_dcerpc_request(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_request *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->alloc_hint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->opnum)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->object, ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)); + NDR_CHECK(ndr_push_dcerpc_object(ndr, NDR_SCALARS, &r->object)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_request(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_request *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->alloc_hint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->opnum)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->object, ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT)); + NDR_CHECK(ndr_pull_dcerpc_object(ndr, NDR_SCALARS, &r->object)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_request(struct ndr_print *ndr, const char *name, const struct dcerpc_request *r) +{ + ndr_print_struct(ndr, name, "dcerpc_request"); + ndr->depth++; + ndr_print_uint32(ndr, "alloc_hint", r->alloc_hint); + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint16(ndr, "opnum", r->opnum); + ndr_print_set_switch_value(ndr, &r->object, ndr->flags & LIBNDR_FLAG_OBJECT_PRESENT); + ndr_print_dcerpc_object(ndr, "object", &r->object); + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "stub_and_verifier", r->stub_and_verifier); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_ack_ctx(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ack_ctx *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->result)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->reason)); + NDR_CHECK(ndr_push_ndr_syntax_id(ndr, NDR_SCALARS, &r->syntax)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_ack_ctx(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ack_ctx *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->result)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->reason)); + NDR_CHECK(ndr_pull_ndr_syntax_id(ndr, NDR_SCALARS, &r->syntax)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ack_ctx(struct ndr_print *ndr, const char *name, const struct dcerpc_ack_ctx *r) +{ + ndr_print_struct(ndr, name, "dcerpc_ack_ctx"); + ndr->depth++; + ndr_print_uint16(ndr, "result", r->result); + ndr_print_uint16(ndr, "reason", r->reason); + ndr_print_ndr_syntax_id(ndr, "syntax", &r->syntax); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind_ack *r) +{ + uint32_t cntr_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_xmit_frag)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->max_recv_frag)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->assoc_group_id)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, strlen(r->secondary_address) + 1)); + NDR_CHECK(ndr_push_charset(ndr, NDR_SCALARS, r->secondary_address, strlen(r->secondary_address) + 1, sizeof(uint8_t), CH_DOS)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad1)); + ndr->flags = _flags_save_DATA_BLOB; + } + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->num_results)); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_results; cntr_ctx_list_0++) { + NDR_CHECK(ndr_push_dcerpc_ack_ctx(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind_ack *r) +{ + uint32_t cntr_ctx_list_0; + TALLOC_CTX *_mem_save_ctx_list_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_xmit_frag)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->max_recv_frag)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->assoc_group_id)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->secondary_address_size)); + NDR_CHECK(ndr_pull_charset(ndr, NDR_SCALARS, &r->secondary_address, r->secondary_address_size, sizeof(uint8_t), CH_DOS)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN4); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad1)); + ndr->flags = _flags_save_DATA_BLOB; + } + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->num_results)); + NDR_PULL_ALLOC_N(ndr, r->ctx_list, r->num_results); + _mem_save_ctx_list_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->ctx_list, 0); + for (cntr_ctx_list_0 = 0; cntr_ctx_list_0 < r->num_results; cntr_ctx_list_0++) { + NDR_CHECK(ndr_pull_dcerpc_ack_ctx(ndr, NDR_SCALARS, &r->ctx_list[cntr_ctx_list_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_ctx_list_0, 0); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_ack *r) +{ + uint32_t cntr_ctx_list_0; + ndr_print_struct(ndr, name, "dcerpc_bind_ack"); + ndr->depth++; + ndr_print_uint16(ndr, "max_xmit_frag", r->max_xmit_frag); + ndr_print_uint16(ndr, "max_recv_frag", r->max_recv_frag); + ndr_print_uint32(ndr, "assoc_group_id", r->assoc_group_id); + ndr_print_uint16(ndr, "secondary_address_size", (ndr->flags & LIBNDR_PRINT_SET_VALUES)?strlen(r->secondary_address) + 1:r->secondary_address_size); + ndr_print_string(ndr, "secondary_address", r->secondary_address); + ndr_print_DATA_BLOB(ndr, "_pad1", r->_pad1); + ndr_print_uint8(ndr, "num_results", r->num_results); + ndr->print(ndr, "%s: ARRAY(%d)", "ctx_list", (int)r->num_results); + ndr->depth++; + for (cntr_ctx_list_0=0;cntr_ctx_list_0<r->num_results;cntr_ctx_list_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_ctx_list_0) != -1) { + ndr_print_dcerpc_ack_ctx(ndr, "ctx_list", &r->ctx_list[cntr_ctx_list_0]); + free(idx_0); + } + } + ndr->depth--; + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind_nak_versions(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind_nak_versions *r) +{ + uint32_t cntr_versions_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->num_versions)); + for (cntr_versions_0 = 0; cntr_versions_0 < r->num_versions; cntr_versions_0++) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->versions[cntr_versions_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_nak_versions(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind_nak_versions *r) +{ + uint32_t cntr_versions_0; + TALLOC_CTX *_mem_save_versions_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->num_versions)); + NDR_PULL_ALLOC_N(ndr, r->versions, r->num_versions); + _mem_save_versions_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->versions, 0); + for (cntr_versions_0 = 0; cntr_versions_0 < r->num_versions; cntr_versions_0++) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->versions[cntr_versions_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_versions_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_nak_versions(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak_versions *r) +{ + uint32_t cntr_versions_0; + ndr_print_struct(ndr, name, "dcerpc_bind_nak_versions"); + ndr->depth++; + ndr_print_uint32(ndr, "num_versions", r->num_versions); + ndr->print(ndr, "%s: ARRAY(%d)", "versions", (int)r->num_versions); + ndr->depth++; + for (cntr_versions_0=0;cntr_versions_0<r->num_versions;cntr_versions_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_versions_0) != -1) { + ndr_print_uint32(ndr, "versions", r->versions[cntr_versions_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_bind_nak_versions_ctr(struct ndr_push *ndr, int ndr_flags, const union dcerpc_bind_nak_versions_ctr *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: { + NDR_CHECK(ndr_push_dcerpc_bind_nak_versions(ndr, NDR_SCALARS, &r->v)); + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_nak_versions_ctr(struct ndr_pull *ndr, int ndr_flags, union dcerpc_bind_nak_versions_ctr *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: { + NDR_CHECK(ndr_pull_dcerpc_bind_nak_versions(ndr, NDR_SCALARS, &r->v)); + break; } + + default: { + break; } + + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: + break; + + default: + break; + + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_nak_versions_ctr(struct ndr_print *ndr, const char *name, const union dcerpc_bind_nak_versions_ctr *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "dcerpc_bind_nak_versions_ctr"); + switch (level) { + case DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED: + ndr_print_dcerpc_bind_nak_versions(ndr, "v", &r->v); + break; + + default: + break; + + } +} + +static enum ndr_err_code ndr_push_dcerpc_bind_nak(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_bind_nak *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->reject_reason)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->versions, r->reject_reason)); + NDR_CHECK(ndr_push_dcerpc_bind_nak_versions_ctr(ndr, NDR_SCALARS, &r->versions)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_dcerpc_bind_nak_versions_ctr(ndr, NDR_BUFFERS, &r->versions)); + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_bind_nak(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_bind_nak *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->reject_reason)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->versions, r->reject_reason)); + NDR_CHECK(ndr_pull_dcerpc_bind_nak_versions_ctr(ndr, NDR_SCALARS, &r->versions)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_dcerpc_bind_nak_versions_ctr(ndr, NDR_BUFFERS, &r->versions)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_bind_nak(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak *r) +{ + ndr_print_struct(ndr, name, "dcerpc_bind_nak"); + ndr->depth++; + ndr_print_uint16(ndr, "reject_reason", r->reject_reason); + ndr_print_set_switch_value(ndr, &r->versions, r->reject_reason); + ndr_print_dcerpc_bind_nak_versions_ctr(ndr, "versions", &r->versions); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_response(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_response *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->alloc_hint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->cancel_count)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_response(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_response *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->alloc_hint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->cancel_count)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_ALIGN8); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->stub_and_verifier)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_response(struct ndr_print *ndr, const char *name, const struct dcerpc_response *r) +{ + ndr_print_struct(ndr, name, "dcerpc_response"); + ndr->depth++; + ndr_print_uint32(ndr, "alloc_hint", r->alloc_hint); + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint8(ndr, "cancel_count", r->cancel_count); + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "stub_and_verifier", r->stub_and_verifier); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_fault(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_fault *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->alloc_hint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->context_id)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->cancel_count)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->status)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_fault(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_fault *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->alloc_hint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->context_id)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->cancel_count)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->status)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->_pad)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_fault(struct ndr_print *ndr, const char *name, const struct dcerpc_fault *r) +{ + ndr_print_struct(ndr, name, "dcerpc_fault"); + ndr->depth++; + ndr_print_uint32(ndr, "alloc_hint", r->alloc_hint); + ndr_print_uint16(ndr, "context_id", r->context_id); + ndr_print_uint8(ndr, "cancel_count", r->cancel_count); + ndr_print_uint32(ndr, "status", r->status); + ndr_print_DATA_BLOB(ndr, "_pad", r->_pad); + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_AuthType(struct ndr_push *ndr, int ndr_flags, enum dcerpc_AuthType r) +{ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_AuthType(struct ndr_pull *ndr, int ndr_flags, enum dcerpc_AuthType *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_AuthType(struct ndr_print *ndr, const char *name, enum dcerpc_AuthType r) +{ + const char *val = NULL; + + switch (r) { + case DCERPC_AUTH_TYPE_NONE: val = "DCERPC_AUTH_TYPE_NONE"; break; + case DCERPC_AUTH_TYPE_KRB5_1: val = "DCERPC_AUTH_TYPE_KRB5_1"; break; + case DCERPC_AUTH_TYPE_SPNEGO: val = "DCERPC_AUTH_TYPE_SPNEGO"; break; + case DCERPC_AUTH_TYPE_NTLMSSP: val = "DCERPC_AUTH_TYPE_NTLMSSP"; break; + case DCERPC_AUTH_TYPE_KRB5: val = "DCERPC_AUTH_TYPE_KRB5"; break; + case DCERPC_AUTH_TYPE_DPA: val = "DCERPC_AUTH_TYPE_DPA"; break; + case DCERPC_AUTH_TYPE_MSN: val = "DCERPC_AUTH_TYPE_MSN"; break; + case DCERPC_AUTH_TYPE_DIGEST: val = "DCERPC_AUTH_TYPE_DIGEST"; break; + case DCERPC_AUTH_TYPE_SCHANNEL: val = "DCERPC_AUTH_TYPE_SCHANNEL"; break; + case DCERPC_AUTH_TYPE_MSMQ: val = "DCERPC_AUTH_TYPE_MSMQ"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +static enum ndr_err_code ndr_push_dcerpc_AuthLevel(struct ndr_push *ndr, int ndr_flags, enum dcerpc_AuthLevel r) +{ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_AuthLevel(struct ndr_pull *ndr, int ndr_flags, enum dcerpc_AuthLevel *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_AuthLevel(struct ndr_print *ndr, const char *name, enum dcerpc_AuthLevel r) +{ + const char *val = NULL; + + switch (r) { + case DCERPC_AUTH_LEVEL_NONE: val = "DCERPC_AUTH_LEVEL_NONE"; break; + case DCERPC_AUTH_LEVEL_CONNECT: val = "DCERPC_AUTH_LEVEL_CONNECT"; break; + case DCERPC_AUTH_LEVEL_CALL: val = "DCERPC_AUTH_LEVEL_CALL"; break; + case DCERPC_AUTH_LEVEL_PACKET: val = "DCERPC_AUTH_LEVEL_PACKET"; break; + case DCERPC_AUTH_LEVEL_INTEGRITY: val = "DCERPC_AUTH_LEVEL_INTEGRITY"; break; + case DCERPC_AUTH_LEVEL_PRIVACY: val = "DCERPC_AUTH_LEVEL_PRIVACY"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_auth(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_dcerpc_AuthType(ndr, NDR_SCALARS, r->auth_type)); + NDR_CHECK(ndr_push_dcerpc_AuthLevel(ndr, NDR_SCALARS, r->auth_level)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->auth_pad_length)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->auth_reserved)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->auth_context_id)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->credentials)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_auth(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_dcerpc_AuthType(ndr, NDR_SCALARS, &r->auth_type)); + NDR_CHECK(ndr_pull_dcerpc_AuthLevel(ndr, NDR_SCALARS, &r->auth_level)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->auth_pad_length)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->auth_reserved)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->auth_context_id)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->credentials)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_auth(struct ndr_print *ndr, const char *name, const struct dcerpc_auth *r) +{ + ndr_print_struct(ndr, name, "dcerpc_auth"); + ndr->depth++; + ndr_print_dcerpc_AuthType(ndr, "auth_type", r->auth_type); + ndr_print_dcerpc_AuthLevel(ndr, "auth_level", r->auth_level); + ndr_print_uint8(ndr, "auth_pad_length", r->auth_pad_length); + ndr_print_uint8(ndr, "auth_reserved", r->auth_reserved); + ndr_print_uint32(ndr, "auth_context_id", r->auth_context_id); + ndr_print_DATA_BLOB(ndr, "credentials", r->credentials); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_auth3(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_auth3(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth3 *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_auth3(struct ndr_print *ndr, const char *name, const struct dcerpc_auth3 *r) +{ + ndr_print_struct(ndr, name, "dcerpc_auth3"); + ndr->depth++; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_orphaned(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_orphaned *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_orphaned(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_orphaned *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_orphaned(struct ndr_print *ndr, const char *name, const struct dcerpc_orphaned *r) +{ + ndr_print_struct(ndr, name, "dcerpc_orphaned"); + ndr->depth++; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_co_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_co_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_push_DATA_BLOB(ndr, NDR_SCALARS, r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_co_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_co_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->_pad)); + { + uint32_t _flags_save_DATA_BLOB = ndr->flags; + ndr_set_flags(&ndr->flags, LIBNDR_FLAG_REMAINING); + NDR_CHECK(ndr_pull_DATA_BLOB(ndr, NDR_SCALARS, &r->auth_info)); + ndr->flags = _flags_save_DATA_BLOB; + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_co_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_co_cancel *r) +{ + ndr_print_struct(ndr, name, "dcerpc_co_cancel"); + ndr->depth++; + ndr_print_uint32(ndr, "_pad", r->_pad); + ndr_print_DATA_BLOB(ndr, "auth_info", r->auth_info); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_cl_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cl_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->id)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_cl_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cl_cancel *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->id)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_cl_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_cl_cancel *r) +{ + ndr_print_struct(ndr, name, "dcerpc_cl_cancel"); + ndr->depth++; + ndr_print_uint32(ndr, "version", r->version); + ndr_print_uint32(ndr, "id", r->id); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_cancel_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cancel_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->id)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->server_is_accepting)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_cancel_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cancel_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->id)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->server_is_accepting)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_cancel_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_cancel_ack *r) +{ + ndr_print_struct(ndr, name, "dcerpc_cancel_ack"); + ndr->depth++; + ndr_print_uint32(ndr, "version", r->version); + ndr_print_uint32(ndr, "id", r->id); + ndr_print_uint32(ndr, "server_is_accepting", r->server_is_accepting); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_fack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_fack *r) +{ + uint32_t cntr_selack_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->version)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->_pad1)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->window_size)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->max_tdsu)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->max_frag_size)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->serial_no)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->selack_size)); + for (cntr_selack_0 = 0; cntr_selack_0 < r->selack_size; cntr_selack_0++) { + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->selack[cntr_selack_0])); + } + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_fack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_fack *r) +{ + uint32_t cntr_selack_0; + TALLOC_CTX *_mem_save_selack_0; + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->version)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->_pad1)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->window_size)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->max_tdsu)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->max_frag_size)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->serial_no)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->selack_size)); + NDR_PULL_ALLOC_N(ndr, r->selack, r->selack_size); + _mem_save_selack_0 = NDR_PULL_GET_MEM_CTX(ndr); + NDR_PULL_SET_MEM_CTX(ndr, r->selack, 0); + for (cntr_selack_0 = 0; cntr_selack_0 < r->selack_size; cntr_selack_0++) { + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->selack[cntr_selack_0])); + } + NDR_PULL_SET_MEM_CTX(ndr, _mem_save_selack_0, 0); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_fack(struct ndr_print *ndr, const char *name, const struct dcerpc_fack *r) +{ + uint32_t cntr_selack_0; + ndr_print_struct(ndr, name, "dcerpc_fack"); + ndr->depth++; + ndr_print_uint32(ndr, "version", r->version); + ndr_print_uint8(ndr, "_pad1", r->_pad1); + ndr_print_uint16(ndr, "window_size", r->window_size); + ndr_print_uint32(ndr, "max_tdsu", r->max_tdsu); + ndr_print_uint32(ndr, "max_frag_size", r->max_frag_size); + ndr_print_uint16(ndr, "serial_no", r->serial_no); + ndr_print_uint16(ndr, "selack_size", r->selack_size); + ndr->print(ndr, "%s: ARRAY(%d)", "selack", (int)r->selack_size); + ndr->depth++; + for (cntr_selack_0=0;cntr_selack_0<r->selack_size;cntr_selack_0++) { + char *idx_0=NULL; + if (asprintf(&idx_0, "[%d]", cntr_selack_0) != -1) { + ndr_print_uint32(ndr, "selack", r->selack[cntr_selack_0]); + free(idx_0); + } + } + ndr->depth--; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ack *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_ack *r) +{ + ndr_print_struct(ndr, name, "dcerpc_ack"); + ndr->depth++; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_ping(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ping *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_ping(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ping *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_ping(struct ndr_print *ndr, const char *name, const struct dcerpc_ping *r) +{ + ndr_print_struct(ndr, name, "dcerpc_ping"); + ndr->depth++; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_shutdown(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_shutdown *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_shutdown(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_shutdown *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_shutdown(struct ndr_print *ndr, const char *name, const struct dcerpc_shutdown *r) +{ + ndr_print_struct(ndr, name, "dcerpc_shutdown"); + ndr->depth++; + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_dcerpc_working(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_working *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_dcerpc_working(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_working *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 1)); + } + if (ndr_flags & NDR_BUFFERS) { + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_working(struct ndr_print *ndr, const char *name, const struct dcerpc_working *r) +{ + ndr_print_struct(ndr, name, "dcerpc_working"); + ndr->depth++; + ndr->depth--; +} + +static enum ndr_err_code ndr_push_dcerpc_pkt_type(struct ndr_push *ndr, int ndr_flags, enum dcerpc_pkt_type r) +{ + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r)); + return NDR_ERR_SUCCESS; +} + +static enum ndr_err_code ndr_pull_dcerpc_pkt_type(struct ndr_pull *ndr, int ndr_flags, enum dcerpc_pkt_type *r) +{ + uint8_t v; + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &v)); + *r = v; + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_pkt_type(struct ndr_print *ndr, const char *name, enum dcerpc_pkt_type r) +{ + const char *val = NULL; + + switch (r) { + case DCERPC_PKT_REQUEST: val = "DCERPC_PKT_REQUEST"; break; + case DCERPC_PKT_PING: val = "DCERPC_PKT_PING"; break; + case DCERPC_PKT_RESPONSE: val = "DCERPC_PKT_RESPONSE"; break; + case DCERPC_PKT_FAULT: val = "DCERPC_PKT_FAULT"; break; + case DCERPC_PKT_WORKING: val = "DCERPC_PKT_WORKING"; break; + case DCERPC_PKT_NOCALL: val = "DCERPC_PKT_NOCALL"; break; + case DCERPC_PKT_REJECT: val = "DCERPC_PKT_REJECT"; break; + case DCERPC_PKT_ACK: val = "DCERPC_PKT_ACK"; break; + case DCERPC_PKT_CL_CANCEL: val = "DCERPC_PKT_CL_CANCEL"; break; + case DCERPC_PKT_FACK: val = "DCERPC_PKT_FACK"; break; + case DCERPC_PKT_CANCEL_ACK: val = "DCERPC_PKT_CANCEL_ACK"; break; + case DCERPC_PKT_BIND: val = "DCERPC_PKT_BIND"; break; + case DCERPC_PKT_BIND_ACK: val = "DCERPC_PKT_BIND_ACK"; break; + case DCERPC_PKT_BIND_NAK: val = "DCERPC_PKT_BIND_NAK"; break; + case DCERPC_PKT_ALTER: val = "DCERPC_PKT_ALTER"; break; + case DCERPC_PKT_ALTER_RESP: val = "DCERPC_PKT_ALTER_RESP"; break; + case DCERPC_PKT_AUTH3: val = "DCERPC_PKT_AUTH3"; break; + case DCERPC_PKT_SHUTDOWN: val = "DCERPC_PKT_SHUTDOWN"; break; + case DCERPC_PKT_CO_CANCEL: val = "DCERPC_PKT_CO_CANCEL"; break; + case DCERPC_PKT_ORPHANED: val = "DCERPC_PKT_ORPHANED"; break; + } + ndr_print_enum(ndr, name, "ENUM", val, r); +} + +static enum ndr_err_code ndr_push_dcerpc_payload(struct ndr_push *ndr, int ndr_flags, const union dcerpc_payload *r) +{ + if (ndr_flags & NDR_SCALARS) { + int level = ndr_push_get_switch_value(ndr, r); + switch (level) { + case DCERPC_PKT_REQUEST: { + NDR_CHECK(ndr_push_dcerpc_request(ndr, NDR_SCALARS, &r->request)); + break; } + + case DCERPC_PKT_PING: { + NDR_CHECK(ndr_push_dcerpc_ping(ndr, NDR_SCALARS, &r->ping)); + break; } + + case DCERPC_PKT_RESPONSE: { + NDR_CHECK(ndr_push_dcerpc_response(ndr, NDR_SCALARS, &r->response)); + break; } + + case DCERPC_PKT_FAULT: { + NDR_CHECK(ndr_push_dcerpc_fault(ndr, NDR_SCALARS, &r->fault)); + break; } + + case DCERPC_PKT_WORKING: { + NDR_CHECK(ndr_push_dcerpc_working(ndr, NDR_SCALARS, &r->working)); + break; } + + case DCERPC_PKT_NOCALL: { + NDR_CHECK(ndr_push_dcerpc_fack(ndr, NDR_SCALARS, &r->nocall)); + break; } + + case DCERPC_PKT_REJECT: { + NDR_CHECK(ndr_push_dcerpc_fault(ndr, NDR_SCALARS, &r->reject)); + break; } + + case DCERPC_PKT_ACK: { + NDR_CHECK(ndr_push_dcerpc_ack(ndr, NDR_SCALARS, &r->ack)); + break; } + + case DCERPC_PKT_CL_CANCEL: { + NDR_CHECK(ndr_push_dcerpc_cl_cancel(ndr, NDR_SCALARS, &r->cl_cancel)); + break; } + + case DCERPC_PKT_FACK: { + NDR_CHECK(ndr_push_dcerpc_fack(ndr, NDR_SCALARS, &r->fack)); + break; } + + case DCERPC_PKT_CANCEL_ACK: { + NDR_CHECK(ndr_push_dcerpc_cancel_ack(ndr, NDR_SCALARS, &r->cancel_ack)); + break; } + + case DCERPC_PKT_BIND: { + NDR_CHECK(ndr_push_dcerpc_bind(ndr, NDR_SCALARS, &r->bind)); + break; } + + case DCERPC_PKT_BIND_ACK: { + NDR_CHECK(ndr_push_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->bind_ack)); + break; } + + case DCERPC_PKT_BIND_NAK: { + NDR_CHECK(ndr_push_dcerpc_bind_nak(ndr, NDR_SCALARS, &r->bind_nak)); + break; } + + case DCERPC_PKT_ALTER: { + NDR_CHECK(ndr_push_dcerpc_bind(ndr, NDR_SCALARS, &r->alter)); + break; } + + case DCERPC_PKT_ALTER_RESP: { + NDR_CHECK(ndr_push_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->alter_resp)); + break; } + + case DCERPC_PKT_SHUTDOWN: { + NDR_CHECK(ndr_push_dcerpc_shutdown(ndr, NDR_SCALARS, &r->shutdown)); + break; } + + case DCERPC_PKT_CO_CANCEL: { + NDR_CHECK(ndr_push_dcerpc_co_cancel(ndr, NDR_SCALARS, &r->co_cancel)); + break; } + + case DCERPC_PKT_ORPHANED: { + NDR_CHECK(ndr_push_dcerpc_orphaned(ndr, NDR_SCALARS, &r->orphaned)); + break; } + + case DCERPC_PKT_AUTH3: { + NDR_CHECK(ndr_push_dcerpc_auth3(ndr, NDR_SCALARS, &r->auth3)); + 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 DCERPC_PKT_REQUEST: + break; + + case DCERPC_PKT_PING: + break; + + case DCERPC_PKT_RESPONSE: + break; + + case DCERPC_PKT_FAULT: + break; + + case DCERPC_PKT_WORKING: + break; + + case DCERPC_PKT_NOCALL: + break; + + case DCERPC_PKT_REJECT: + break; + + case DCERPC_PKT_ACK: + break; + + case DCERPC_PKT_CL_CANCEL: + break; + + case DCERPC_PKT_FACK: + break; + + case DCERPC_PKT_CANCEL_ACK: + break; + + case DCERPC_PKT_BIND: + break; + + case DCERPC_PKT_BIND_ACK: + break; + + case DCERPC_PKT_BIND_NAK: + NDR_CHECK(ndr_push_dcerpc_bind_nak(ndr, NDR_BUFFERS, &r->bind_nak)); + break; + + case DCERPC_PKT_ALTER: + break; + + case DCERPC_PKT_ALTER_RESP: + break; + + case DCERPC_PKT_SHUTDOWN: + break; + + case DCERPC_PKT_CO_CANCEL: + break; + + case DCERPC_PKT_ORPHANED: + break; + + case DCERPC_PKT_AUTH3: + 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_dcerpc_payload(struct ndr_pull *ndr, int ndr_flags, union dcerpc_payload *r) +{ + int level; + level = ndr_pull_get_switch_value(ndr, r); + if (ndr_flags & NDR_SCALARS) { + switch (level) { + case DCERPC_PKT_REQUEST: { + NDR_CHECK(ndr_pull_dcerpc_request(ndr, NDR_SCALARS, &r->request)); + break; } + + case DCERPC_PKT_PING: { + NDR_CHECK(ndr_pull_dcerpc_ping(ndr, NDR_SCALARS, &r->ping)); + break; } + + case DCERPC_PKT_RESPONSE: { + NDR_CHECK(ndr_pull_dcerpc_response(ndr, NDR_SCALARS, &r->response)); + break; } + + case DCERPC_PKT_FAULT: { + NDR_CHECK(ndr_pull_dcerpc_fault(ndr, NDR_SCALARS, &r->fault)); + break; } + + case DCERPC_PKT_WORKING: { + NDR_CHECK(ndr_pull_dcerpc_working(ndr, NDR_SCALARS, &r->working)); + break; } + + case DCERPC_PKT_NOCALL: { + NDR_CHECK(ndr_pull_dcerpc_fack(ndr, NDR_SCALARS, &r->nocall)); + break; } + + case DCERPC_PKT_REJECT: { + NDR_CHECK(ndr_pull_dcerpc_fault(ndr, NDR_SCALARS, &r->reject)); + break; } + + case DCERPC_PKT_ACK: { + NDR_CHECK(ndr_pull_dcerpc_ack(ndr, NDR_SCALARS, &r->ack)); + break; } + + case DCERPC_PKT_CL_CANCEL: { + NDR_CHECK(ndr_pull_dcerpc_cl_cancel(ndr, NDR_SCALARS, &r->cl_cancel)); + break; } + + case DCERPC_PKT_FACK: { + NDR_CHECK(ndr_pull_dcerpc_fack(ndr, NDR_SCALARS, &r->fack)); + break; } + + case DCERPC_PKT_CANCEL_ACK: { + NDR_CHECK(ndr_pull_dcerpc_cancel_ack(ndr, NDR_SCALARS, &r->cancel_ack)); + break; } + + case DCERPC_PKT_BIND: { + NDR_CHECK(ndr_pull_dcerpc_bind(ndr, NDR_SCALARS, &r->bind)); + break; } + + case DCERPC_PKT_BIND_ACK: { + NDR_CHECK(ndr_pull_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->bind_ack)); + break; } + + case DCERPC_PKT_BIND_NAK: { + NDR_CHECK(ndr_pull_dcerpc_bind_nak(ndr, NDR_SCALARS, &r->bind_nak)); + break; } + + case DCERPC_PKT_ALTER: { + NDR_CHECK(ndr_pull_dcerpc_bind(ndr, NDR_SCALARS, &r->alter)); + break; } + + case DCERPC_PKT_ALTER_RESP: { + NDR_CHECK(ndr_pull_dcerpc_bind_ack(ndr, NDR_SCALARS, &r->alter_resp)); + break; } + + case DCERPC_PKT_SHUTDOWN: { + NDR_CHECK(ndr_pull_dcerpc_shutdown(ndr, NDR_SCALARS, &r->shutdown)); + break; } + + case DCERPC_PKT_CO_CANCEL: { + NDR_CHECK(ndr_pull_dcerpc_co_cancel(ndr, NDR_SCALARS, &r->co_cancel)); + break; } + + case DCERPC_PKT_ORPHANED: { + NDR_CHECK(ndr_pull_dcerpc_orphaned(ndr, NDR_SCALARS, &r->orphaned)); + break; } + + case DCERPC_PKT_AUTH3: { + NDR_CHECK(ndr_pull_dcerpc_auth3(ndr, NDR_SCALARS, &r->auth3)); + break; } + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + if (ndr_flags & NDR_BUFFERS) { + switch (level) { + case DCERPC_PKT_REQUEST: + break; + + case DCERPC_PKT_PING: + break; + + case DCERPC_PKT_RESPONSE: + break; + + case DCERPC_PKT_FAULT: + break; + + case DCERPC_PKT_WORKING: + break; + + case DCERPC_PKT_NOCALL: + break; + + case DCERPC_PKT_REJECT: + break; + + case DCERPC_PKT_ACK: + break; + + case DCERPC_PKT_CL_CANCEL: + break; + + case DCERPC_PKT_FACK: + break; + + case DCERPC_PKT_CANCEL_ACK: + break; + + case DCERPC_PKT_BIND: + break; + + case DCERPC_PKT_BIND_ACK: + break; + + case DCERPC_PKT_BIND_NAK: + NDR_CHECK(ndr_pull_dcerpc_bind_nak(ndr, NDR_BUFFERS, &r->bind_nak)); + break; + + case DCERPC_PKT_ALTER: + break; + + case DCERPC_PKT_ALTER_RESP: + break; + + case DCERPC_PKT_SHUTDOWN: + break; + + case DCERPC_PKT_CO_CANCEL: + break; + + case DCERPC_PKT_ORPHANED: + break; + + case DCERPC_PKT_AUTH3: + break; + + default: + return ndr_pull_error(ndr, NDR_ERR_BAD_SWITCH, "Bad switch value %u", level); + } + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_dcerpc_payload(struct ndr_print *ndr, const char *name, const union dcerpc_payload *r) +{ + int level; + level = ndr_print_get_switch_value(ndr, r); + ndr_print_union(ndr, name, level, "dcerpc_payload"); + switch (level) { + case DCERPC_PKT_REQUEST: + ndr_print_dcerpc_request(ndr, "request", &r->request); + break; + + case DCERPC_PKT_PING: + ndr_print_dcerpc_ping(ndr, "ping", &r->ping); + break; + + case DCERPC_PKT_RESPONSE: + ndr_print_dcerpc_response(ndr, "response", &r->response); + break; + + case DCERPC_PKT_FAULT: + ndr_print_dcerpc_fault(ndr, "fault", &r->fault); + break; + + case DCERPC_PKT_WORKING: + ndr_print_dcerpc_working(ndr, "working", &r->working); + break; + + case DCERPC_PKT_NOCALL: + ndr_print_dcerpc_fack(ndr, "nocall", &r->nocall); + break; + + case DCERPC_PKT_REJECT: + ndr_print_dcerpc_fault(ndr, "reject", &r->reject); + break; + + case DCERPC_PKT_ACK: + ndr_print_dcerpc_ack(ndr, "ack", &r->ack); + break; + + case DCERPC_PKT_CL_CANCEL: + ndr_print_dcerpc_cl_cancel(ndr, "cl_cancel", &r->cl_cancel); + break; + + case DCERPC_PKT_FACK: + ndr_print_dcerpc_fack(ndr, "fack", &r->fack); + break; + + case DCERPC_PKT_CANCEL_ACK: + ndr_print_dcerpc_cancel_ack(ndr, "cancel_ack", &r->cancel_ack); + break; + + case DCERPC_PKT_BIND: + ndr_print_dcerpc_bind(ndr, "bind", &r->bind); + break; + + case DCERPC_PKT_BIND_ACK: + ndr_print_dcerpc_bind_ack(ndr, "bind_ack", &r->bind_ack); + break; + + case DCERPC_PKT_BIND_NAK: + ndr_print_dcerpc_bind_nak(ndr, "bind_nak", &r->bind_nak); + break; + + case DCERPC_PKT_ALTER: + ndr_print_dcerpc_bind(ndr, "alter", &r->alter); + break; + + case DCERPC_PKT_ALTER_RESP: + ndr_print_dcerpc_bind_ack(ndr, "alter_resp", &r->alter_resp); + break; + + case DCERPC_PKT_SHUTDOWN: + ndr_print_dcerpc_shutdown(ndr, "shutdown", &r->shutdown); + break; + + case DCERPC_PKT_CO_CANCEL: + ndr_print_dcerpc_co_cancel(ndr, "co_cancel", &r->co_cancel); + break; + + case DCERPC_PKT_ORPHANED: + ndr_print_dcerpc_orphaned(ndr, "orphaned", &r->orphaned); + break; + + case DCERPC_PKT_AUTH3: + ndr_print_dcerpc_auth3(ndr, "auth3", &r->auth3); + break; + + default: + ndr_print_bad_level(ndr, name, level); + } +} + +_PUBLIC_ enum ndr_err_code ndr_push_ncacn_packet(struct ndr_push *ndr, int ndr_flags, const struct ncacn_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->rpc_vers)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->rpc_vers_minor)); + NDR_CHECK(ndr_push_dcerpc_pkt_type(ndr, NDR_SCALARS, r->ptype)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->pfc_flags)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->drep, 4)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->frag_length)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->auth_length)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->call_id)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_ncacn_packet(struct ndr_pull *ndr, int ndr_flags, struct ncacn_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->rpc_vers)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->rpc_vers_minor)); + NDR_CHECK(ndr_pull_dcerpc_pkt_type(ndr, NDR_SCALARS, &r->ptype)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->pfc_flags)); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->drep, 4)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->frag_length)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->auth_length)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->call_id)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_ncacn_packet(struct ndr_print *ndr, const char *name, const struct ncacn_packet *r) +{ + ndr_print_struct(ndr, name, "ncacn_packet"); + ndr->depth++; + ndr_print_uint8(ndr, "rpc_vers", r->rpc_vers); + ndr_print_uint8(ndr, "rpc_vers_minor", r->rpc_vers_minor); + ndr_print_dcerpc_pkt_type(ndr, "ptype", r->ptype); + ndr_print_uint8(ndr, "pfc_flags", r->pfc_flags); + ndr_print_array_uint8(ndr, "drep", r->drep, 4); + ndr_print_uint16(ndr, "frag_length", r->frag_length); + ndr_print_uint16(ndr, "auth_length", r->auth_length); + ndr_print_uint32(ndr, "call_id", r->call_id); + ndr_print_set_switch_value(ndr, &r->u, r->ptype); + ndr_print_dcerpc_payload(ndr, "u", &r->u); + ndr->depth--; +} + +_PUBLIC_ enum ndr_err_code ndr_push_ncadg_packet(struct ndr_push *ndr, int ndr_flags, const struct ncadg_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_push_align(ndr, 4)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->rpc_vers)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->ptype)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->pfc_flags)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->ncadg_flags)); + NDR_CHECK(ndr_push_array_uint8(ndr, NDR_SCALARS, r->drep, 3)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->serial_high)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->iface)); + NDR_CHECK(ndr_push_GUID(ndr, NDR_SCALARS, &r->activity)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->server_boot)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->iface_version)); + NDR_CHECK(ndr_push_uint32(ndr, NDR_SCALARS, r->seq_num)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->opnum)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->ihint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->ahint)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->len)); + NDR_CHECK(ndr_push_uint16(ndr, NDR_SCALARS, r->fragnum)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->auth_proto)); + NDR_CHECK(ndr_push_uint8(ndr, NDR_SCALARS, r->serial_low)); + NDR_CHECK(ndr_push_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_push_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ enum ndr_err_code ndr_pull_ncadg_packet(struct ndr_pull *ndr, int ndr_flags, struct ncadg_packet *r) +{ + if (ndr_flags & NDR_SCALARS) { + NDR_CHECK(ndr_pull_align(ndr, 4)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->rpc_vers)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->ptype)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->pfc_flags)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->ncadg_flags)); + NDR_CHECK(ndr_pull_array_uint8(ndr, NDR_SCALARS, r->drep, 3)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->serial_high)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->object)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->iface)); + NDR_CHECK(ndr_pull_GUID(ndr, NDR_SCALARS, &r->activity)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->server_boot)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->iface_version)); + NDR_CHECK(ndr_pull_uint32(ndr, NDR_SCALARS, &r->seq_num)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->opnum)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->ihint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->ahint)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->len)); + NDR_CHECK(ndr_pull_uint16(ndr, NDR_SCALARS, &r->fragnum)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->auth_proto)); + NDR_CHECK(ndr_pull_uint8(ndr, NDR_SCALARS, &r->serial_low)); + NDR_CHECK(ndr_pull_set_switch_value(ndr, &r->u, r->ptype)); + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_SCALARS, &r->u)); + } + if (ndr_flags & NDR_BUFFERS) { + NDR_CHECK(ndr_pull_dcerpc_payload(ndr, NDR_BUFFERS, &r->u)); + } + return NDR_ERR_SUCCESS; +} + +_PUBLIC_ void ndr_print_ncadg_packet(struct ndr_print *ndr, const char *name, const struct ncadg_packet *r) +{ + ndr_print_struct(ndr, name, "ncadg_packet"); + ndr->depth++; + ndr_print_uint8(ndr, "rpc_vers", r->rpc_vers); + ndr_print_uint8(ndr, "ptype", r->ptype); + ndr_print_uint8(ndr, "pfc_flags", r->pfc_flags); + ndr_print_uint8(ndr, "ncadg_flags", r->ncadg_flags); + ndr_print_array_uint8(ndr, "drep", r->drep, 3); + ndr_print_uint8(ndr, "serial_high", r->serial_high); + ndr_print_GUID(ndr, "object", &r->object); + ndr_print_GUID(ndr, "iface", &r->iface); + ndr_print_GUID(ndr, "activity", &r->activity); + ndr_print_uint32(ndr, "server_boot", r->server_boot); + ndr_print_uint32(ndr, "iface_version", r->iface_version); + ndr_print_uint32(ndr, "seq_num", r->seq_num); + ndr_print_uint16(ndr, "opnum", r->opnum); + ndr_print_uint16(ndr, "ihint", r->ihint); + ndr_print_uint16(ndr, "ahint", r->ahint); + ndr_print_uint16(ndr, "len", r->len); + ndr_print_uint16(ndr, "fragnum", r->fragnum); + ndr_print_uint8(ndr, "auth_proto", r->auth_proto); + ndr_print_uint8(ndr, "serial_low", r->serial_low); + ndr_print_set_switch_value(ndr, &r->u, r->ptype); + ndr_print_dcerpc_payload(ndr, "u", &r->u); + ndr->depth--; +} + diff --git a/librpc/gen_ndr/ndr_dcerpc.h b/librpc/gen_ndr/ndr_dcerpc.h new file mode 100644 index 0000000000..9baa089d8a --- /dev/null +++ b/librpc/gen_ndr/ndr_dcerpc.h @@ -0,0 +1,65 @@ +/* header auto-generated by pidl */ + +#include "librpc/ndr/libndr.h" +#include "../librpc/gen_ndr/dcerpc.h" + +#ifndef _HEADER_NDR_dcerpc +#define _HEADER_NDR_dcerpc + +#define NDR_DCERPC_CALL_COUNT (0) +void ndr_print_dcerpc_ctx_list(struct ndr_print *ndr, const char *name, const struct dcerpc_ctx_list *r); +void ndr_print_dcerpc_bind(struct ndr_print *ndr, const char *name, const struct dcerpc_bind *r); +void ndr_print_dcerpc_empty(struct ndr_print *ndr, const char *name, const struct dcerpc_empty *r); +void ndr_print_dcerpc_object(struct ndr_print *ndr, const char *name, const union dcerpc_object *r); +void ndr_print_dcerpc_request(struct ndr_print *ndr, const char *name, const struct dcerpc_request *r); +void ndr_print_dcerpc_ack_ctx(struct ndr_print *ndr, const char *name, const struct dcerpc_ack_ctx *r); +void ndr_print_dcerpc_bind_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_ack *r); +void ndr_print_dcerpc_bind_nak_versions(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak_versions *r); +void ndr_print_dcerpc_bind_nak_versions_ctr(struct ndr_print *ndr, const char *name, const union dcerpc_bind_nak_versions_ctr *r); +void ndr_print_dcerpc_bind_nak(struct ndr_print *ndr, const char *name, const struct dcerpc_bind_nak *r); +void ndr_print_dcerpc_response(struct ndr_print *ndr, const char *name, const struct dcerpc_response *r); +void ndr_print_dcerpc_fault(struct ndr_print *ndr, const char *name, const struct dcerpc_fault *r); +void ndr_print_dcerpc_AuthType(struct ndr_print *ndr, const char *name, enum dcerpc_AuthType r); +void ndr_print_dcerpc_AuthLevel(struct ndr_print *ndr, const char *name, enum dcerpc_AuthLevel r); +enum ndr_err_code ndr_push_dcerpc_auth(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth *r); +enum ndr_err_code ndr_pull_dcerpc_auth(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth *r); +void ndr_print_dcerpc_auth(struct ndr_print *ndr, const char *name, const struct dcerpc_auth *r); +enum ndr_err_code ndr_push_dcerpc_auth3(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_auth3 *r); +enum ndr_err_code ndr_pull_dcerpc_auth3(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_auth3 *r); +void ndr_print_dcerpc_auth3(struct ndr_print *ndr, const char *name, const struct dcerpc_auth3 *r); +enum ndr_err_code ndr_push_dcerpc_orphaned(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_orphaned *r); +enum ndr_err_code ndr_pull_dcerpc_orphaned(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_orphaned *r); +void ndr_print_dcerpc_orphaned(struct ndr_print *ndr, const char *name, const struct dcerpc_orphaned *r); +enum ndr_err_code ndr_push_dcerpc_co_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_co_cancel *r); +enum ndr_err_code ndr_pull_dcerpc_co_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_co_cancel *r); +void ndr_print_dcerpc_co_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_co_cancel *r); +enum ndr_err_code ndr_push_dcerpc_cl_cancel(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cl_cancel *r); +enum ndr_err_code ndr_pull_dcerpc_cl_cancel(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cl_cancel *r); +void ndr_print_dcerpc_cl_cancel(struct ndr_print *ndr, const char *name, const struct dcerpc_cl_cancel *r); +enum ndr_err_code ndr_push_dcerpc_cancel_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_cancel_ack *r); +enum ndr_err_code ndr_pull_dcerpc_cancel_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_cancel_ack *r); +void ndr_print_dcerpc_cancel_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_cancel_ack *r); +enum ndr_err_code ndr_push_dcerpc_fack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_fack *r); +enum ndr_err_code ndr_pull_dcerpc_fack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_fack *r); +void ndr_print_dcerpc_fack(struct ndr_print *ndr, const char *name, const struct dcerpc_fack *r); +enum ndr_err_code ndr_push_dcerpc_ack(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ack *r); +enum ndr_err_code ndr_pull_dcerpc_ack(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ack *r); +void ndr_print_dcerpc_ack(struct ndr_print *ndr, const char *name, const struct dcerpc_ack *r); +enum ndr_err_code ndr_push_dcerpc_ping(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_ping *r); +enum ndr_err_code ndr_pull_dcerpc_ping(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_ping *r); +void ndr_print_dcerpc_ping(struct ndr_print *ndr, const char *name, const struct dcerpc_ping *r); +enum ndr_err_code ndr_push_dcerpc_shutdown(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_shutdown *r); +enum ndr_err_code ndr_pull_dcerpc_shutdown(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_shutdown *r); +void ndr_print_dcerpc_shutdown(struct ndr_print *ndr, const char *name, const struct dcerpc_shutdown *r); +enum ndr_err_code ndr_push_dcerpc_working(struct ndr_push *ndr, int ndr_flags, const struct dcerpc_working *r); +enum ndr_err_code ndr_pull_dcerpc_working(struct ndr_pull *ndr, int ndr_flags, struct dcerpc_working *r); +void ndr_print_dcerpc_working(struct ndr_print *ndr, const char *name, const struct dcerpc_working *r); +void ndr_print_dcerpc_pkt_type(struct ndr_print *ndr, const char *name, enum dcerpc_pkt_type r); +void ndr_print_dcerpc_payload(struct ndr_print *ndr, const char *name, const union dcerpc_payload *r); +enum ndr_err_code ndr_push_ncacn_packet(struct ndr_push *ndr, int ndr_flags, const struct ncacn_packet *r); +enum ndr_err_code ndr_pull_ncacn_packet(struct ndr_pull *ndr, int ndr_flags, struct ncacn_packet *r); +void ndr_print_ncacn_packet(struct ndr_print *ndr, const char *name, const struct ncacn_packet *r); +enum ndr_err_code ndr_push_ncadg_packet(struct ndr_push *ndr, int ndr_flags, const struct ncadg_packet *r); +enum ndr_err_code ndr_pull_ncadg_packet(struct ndr_pull *ndr, int ndr_flags, struct ncadg_packet *r); +void ndr_print_ncadg_packet(struct ndr_print *ndr, const char *name, const struct ncadg_packet *r); +#endif /* _HEADER_NDR_dcerpc */ diff --git a/source4/librpc/idl/dcerpc.idl b/librpc/idl/dcerpc.idl index 7c0abe6ab8..3ec416d5c6 100644 --- a/source4/librpc/idl/dcerpc.idl +++ b/librpc/idl/dcerpc.idl @@ -33,7 +33,7 @@ interface dcerpc typedef struct { } dcerpc_empty; - + typedef [nodiscriminant] union { [default] dcerpc_empty empty; [case(LIBNDR_FLAG_OBJECT_PRESENT)] GUID object; @@ -75,7 +75,7 @@ interface dcerpc uint32 num_versions; uint32 versions[num_versions]; } dcerpc_bind_nak_versions; - + typedef [nodiscriminant] union { [case(DECRPC_BIND_PROTOCOL_VERSION_NOT_SUPPORTED)] dcerpc_bind_nak_versions v; [default] ; @@ -145,7 +145,7 @@ interface dcerpc const uint8 DCERPC_AUTH_LEVEL_DEFAULT = DCERPC_AUTH_LEVEL_CONNECT; typedef [public] struct { - dcerpc_AuthType auth_type; + dcerpc_AuthType auth_type; dcerpc_AuthLevel auth_level; uint8 auth_pad_length; uint8 auth_reserved; @@ -176,7 +176,7 @@ interface dcerpc } dcerpc_cl_cancel; typedef [public] struct { - uint32 version; + uint32 version; uint32 id; boolean32 server_is_accepting; } dcerpc_cancel_ack; @@ -200,7 +200,7 @@ interface dcerpc typedef [public] struct { } dcerpc_shutdown; - + typedef [public] struct { } dcerpc_working; diff --git a/selftest/SocketWrapper.pm b/selftest/SocketWrapper.pm index e63605b8df..ef8058da79 100644 --- a/selftest/SocketWrapper.pm +++ b/selftest/SocketWrapper.pm @@ -1,7 +1,21 @@ #!/usr/bin/perl # Bootstrap Samba and run a number of tests against it. # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org> -# Published under the GNU GPL, v3 or later. + +# 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/>. + + package SocketWrapper; diff --git a/selftest/Subunit.pm b/selftest/Subunit.pm index 05e51da541..19af636d0b 100644 --- a/selftest/Subunit.pm +++ b/selftest/Subunit.pm @@ -1,3 +1,19 @@ +# Simple Perl module for parsing the Subunit protocol +# Copyright (C) 2008 Jelmer Vernooij <jelmer@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/>. + package Subunit; require Exporter; diff --git a/selftest/output/buildfarm.pm b/selftest/output/buildfarm.pm index cee6c1e63a..77ea26621b 100644 --- a/selftest/output/buildfarm.pm +++ b/selftest/output/buildfarm.pm @@ -1,4 +1,19 @@ #!/usr/bin/perl +# Buildfarm output for selftest +# Copyright (C) 2008 Jelmer Vernooij <jelmer@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/>. package output::buildfarm; diff --git a/selftest/output/html.pm b/selftest/output/html.pm index 1049527129..e490765d06 100644 --- a/selftest/output/html.pm +++ b/selftest/output/html.pm @@ -1,5 +1,19 @@ #!/usr/bin/perl - +# HTML output for selftest +# Copyright (C) 2008 Jelmer Vernooij <jelmer@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/>. package output::html; use Exporter; @ISA = qw(Exporter); diff --git a/selftest/output/plain.pm b/selftest/output/plain.pm index 82a73ab932..5312a9e27b 100644 --- a/selftest/output/plain.pm +++ b/selftest/output/plain.pm @@ -1,5 +1,19 @@ #!/usr/bin/perl - +# Plain text output for selftest +# Copyright (C) 2008 Jelmer Vernooij <jelmer@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/>. package output::plain; use Exporter; @ISA = qw(Exporter); diff --git a/selftest/selftest.pl b/selftest/selftest.pl index ef4c385d33..3653523541 100755 --- a/selftest/selftest.pl +++ b/selftest/selftest.pl @@ -2,7 +2,19 @@ # Bootstrap Samba and run a number of tests against it. # Copyright (C) 2005-2008 Jelmer Vernooij <jelmer@samba.org> # Copyright (C) 2007-2009 Stefan Metzmacher <metze@samba.org> -# Published under the GNU GPL, v3 or later. + +# 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/>. =pod diff --git a/selftest/target/Samba3.pm b/selftest/target/Samba3.pm index e1bea16523..0b176d601c 100644 --- a/selftest/target/Samba3.pm +++ b/selftest/target/Samba3.pm @@ -41,6 +41,9 @@ sub teardown_env($$) $self->stop_sig_term($smbdpid); $self->stop_sig_term($nmbdpid); $self->stop_sig_term($winbinddpid); + + sleep(2); + $self->stop_sig_kill($smbdpid); $self->stop_sig_kill($nmbdpid); $self->stop_sig_kill($winbinddpid); @@ -123,9 +126,8 @@ sub setup_dc($$) $dc_options); $self->check_or_start($vars, - ($ENV{NMBD_MAXTIME} or 2700), - ($ENV{WINBINDD_MAXTIME} or 2700), - ($ENV{SMBD_MAXTIME} or 2700)); + ($ENV{SMBD_MAXTIME} or 2700), + "yes", "yes", "yes"); $self->wait_for_start($vars); @@ -142,6 +144,7 @@ sub setup_member($$$) my $member_options = " security = domain + server signing = on "; my $ret = $self->provision($prefix, "LOCALMEMBER3", @@ -160,9 +163,8 @@ sub setup_member($$$) system($cmd) == 0 or die("Join failed\n$cmd"); $self->check_or_start($ret, - ($ENV{NMBD_MAXTIME} or 2700), - ($ENV{WINBINDD_MAXTIME} or 2700), - ($ENV{SMBD_MAXTIME} or 2700)); + ($ENV{SMBD_MAXTIME} or 2700), + "yes", "yes", "yes"); $self->wait_for_start($ret); @@ -187,7 +189,7 @@ sub stop_sig_term($$) { sub stop_sig_kill($$) { my ($self, $pid) = @_; - kill("KILL", $pid) or warn("Unable to kill $pid: $!"); + kill("ALRM", $pid) or warn("Unable to kill $pid: $!"); } sub write_pid($$$) @@ -209,8 +211,8 @@ sub read_pid($$) return $pid; } -sub check_or_start($$$$) { - my ($self, $env_vars, $nmbd_maxtime, $winbindd_maxtime, $smbd_maxtime) = @_; +sub check_or_start($$$$$) { + my ($self, $env_vars, $maxtime, $nmbd, $winbindd, $smbd) = @_; unlink($env_vars->{NMBD_TEST_LOG}); print "STARTING NMBD..."; @@ -226,13 +228,13 @@ sub check_or_start($$$$) { $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; - if ($nmbd_maxtime eq "skip") { + if ($nmbd ne "yes") { $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { my $signame = shift; print("Skip nmbd received signal $signame"); exit 0; }; - sleep(999999); + sleep($maxtime); exit 0; } @@ -243,7 +245,7 @@ sub check_or_start($$$$) { $ENV{MAKE_TEST_BINARY} = $self->binpath("nmbd"); - my @preargs = ($self->binpath("timelimit"), $nmbd_maxtime); + my @preargs = ($self->binpath("timelimit"), $maxtime); if(defined($ENV{NMBD_VALGRIND})) { @preargs = split(/ /, $ENV{NMBD_VALGRIND}); } @@ -267,13 +269,13 @@ sub check_or_start($$$$) { $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; - if ($winbindd_maxtime eq "skip") { + if ($winbindd ne "yes") { $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { my $signame = shift; print("Skip winbindd received signal $signame"); exit 0; }; - sleep(999999); + sleep($maxtime); exit 0; } @@ -284,7 +286,7 @@ sub check_or_start($$$$) { $ENV{MAKE_TEST_BINARY} = $self->binpath("winbindd"); - my @preargs = ($self->binpath("timelimit"), $winbindd_maxtime); + my @preargs = ($self->binpath("timelimit"), $maxtime); if(defined($ENV{WINBINDD_VALGRIND})) { @preargs = split(/ /, $ENV{WINBINDD_VALGRIND}); } @@ -308,13 +310,13 @@ sub check_or_start($$$$) { $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD}; $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP}; - if ($smbd_maxtime eq "skip") { + if ($smbd ne "yes") { $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { my $signame = shift; print("Skip smbd received signal $signame"); exit 0; }; - sleep(999999); + sleep($maxtime); exit 0; } @@ -323,7 +325,7 @@ sub check_or_start($$$$) { if (defined($ENV{SMBD_OPTIONS})) { @optargs = split(/ /, $ENV{SMBD_OPTIONS}); } - my @preargs = ($self->binpath("timelimit"), $smbd_maxtime); + my @preargs = ($self->binpath("timelimit"), $maxtime); if(defined($ENV{SMBD_VALGRIND})) { @preargs = split(/ /,$ENV{SMBD_VALGRIND}); } diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm index 71dddf6939..1058ac66e0 100644 --- a/selftest/target/Samba4.pm +++ b/selftest/target/Samba4.pm @@ -103,8 +103,8 @@ sub check_or_start($$$) SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE}); my $valgrind = ""; - if (defined($ENV{SMBD_VALGRIND})) { - $valgrind = $ENV{SMBD_VALGRIND}; + if (defined($ENV{SAMBA_VALGRIND})) { + $valgrind = $ENV{SAMBA_VALGRIND}; } $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG}; @@ -122,8 +122,8 @@ sub check_or_start($$$) if (defined($max_time)) { $optarg = "--maximum-runtime=$max_time "; } - if (defined($ENV{SMBD_OPTIONS})) { - $optarg.= " $ENV{SMBD_OPTIONS}"; + if (defined($ENV{SAMBA_OPTIONS})) { + $optarg.= " $ENV{SAMBA_OPTIONS}"; } my $samba = $self->bindir_path("samba"); my $ret = system("$valgrind $samba $optarg $env_vars->{CONFIGURATION} -M single -i --leak-report-full"); diff --git a/source3/Makefile.in b/source3/Makefile.in index cf74182f27..18ee7fec1c 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -73,6 +73,7 @@ WINBIND_NSS_EXTRA_LIBS=@WINBIND_NSS_EXTRA_LIBS@ WINBIND_NSS_PTHREAD=@WINBIND_NSS_PTHREAD@ PAM_WINBIND_EXTRA_LIBS=@PAM_WINBIND_EXTRA_LIBS@ DNSSD_LIBS=@DNSSD_LIBS@ +AVAHI_LIBS=@AVAHI_LIBS@ POPT_LIBS=@POPTLIBS@ LIBTALLOC_LIBS=@LIBTALLOC_LIBS@ LIBTDB_LIBS=@LIBTDB_LIBS@ @@ -158,7 +159,7 @@ CODEPAGEDIR = @codepagedir@ # the directory where pid files go PIDDIR = @piddir@ -FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) -I$(CTDBDIR)/include $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 -I../source4 +FLAGS = -I. -I$(srcdir) @FLAGS1@ @SAMBA_CPPFLAGS@ $(CPPFLAGS) $(ISA) -I$(srcdir)/lib -I.. -D_SAMBA_BUILD_=3 -I../source4 PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DPRIVATE_DIR=\"$(PRIVATE_DIR)\" \ @@ -173,7 +174,6 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DMODULESDIR=\"$(MODULESDIR)\" \ -DLOGFILEBASE=\"$(LOGFILEBASE)\" \ -DSHLIBEXT=\"@SHLIBEXT@\" \ - -DCTDBDIR=\"$(CTDBDIR)\" \ -DNCALRPCDIR=\"$(NCALRPCDIR)\" \ -DCONFIGDIR=\"$(CONFIGDIR)\" \ -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \ @@ -255,6 +255,8 @@ AFS_OBJ = lib/afs.o AFS_SETTOKEN_OBJ = lib/afs_settoken.o +AVAHI_OBJ = @AVAHI_OBJ@ + SERVER_MUTEX_OBJ = lib/server_mutex.o PASSCHANGE_OBJ = libsmb/passchange.o @@ -282,7 +284,8 @@ LIBNDR_OBJ = ../librpc/ndr/ndr_basic.o \ ../librpc/ndr/ndr_sec_helper.o \ librpc/ndr/ndr_string.o \ ../librpc/ndr/uuid.o \ - librpc/ndr/util.o + librpc/ndr/util.o \ + ../librpc/gen_ndr/ndr_dcerpc.o RPCCLIENT_NDR_OBJ = rpc_client/ndr.o @@ -316,7 +319,7 @@ RPC_PARSE_OBJ0 = rpc_parse/parse_prs.o rpc_parse/parse_misc.o # this includes only the low level parse code, not stuff # that requires knowledge of security contexts -RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) rpc_parse/parse_sec.o +RPC_PARSE_OBJ1 = $(RPC_PARSE_OBJ0) RPC_PARSE_OBJ2 = rpc_parse/parse_rpc.o \ rpc_client/init_netlogon.o \ @@ -364,7 +367,8 @@ LIB_OBJ = $(LIBSAMBAUTIL_OBJ) $(UTIL_OBJ) $(CRYPTO_OBJ) \ lib/util.o lib/util_sock.o lib/sock_exec.o lib/util_sec.o \ lib/substitute.o lib/dbwrap_util.o \ lib/ms_fnmatch.o lib/select.o lib/errmap_unix.o \ - lib/tallocmsg.o lib/dmallocmsg.o libsmb/smb_signing.o \ + lib/tallocmsg.o lib/dmallocmsg.o \ + libsmb/clisigning.o libsmb/smb_signing.o \ lib/iconv.o lib/pam_errors.o intl/lang_tdb.o \ lib/conn_tdb.o lib/adt_tree.o lib/gencache.o \ lib/module.o lib/events.o @LIBTEVENT_OBJ0@ \ @@ -687,6 +691,7 @@ VFS_ONEFS_OBJ = modules/vfs_onefs.o modules/onefs_acl.o modules/onefs_system.o \ VFS_ONEFS_SHADOW_COPY_OBJ = modules/vfs_onefs_shadow_copy.o modules/onefs_shadow_copy.o PERFCOUNT_ONEFS_OBJ = modules/perfcount_onefs.o PERFCOUNT_TEST_OBJ = modules/perfcount_test.o +VFS_DIRSORT_OBJ = modules/vfs_dirsort.o PLAINTEXT_AUTH_OBJ = auth/pampass.o auth/pass_check.o @@ -731,7 +736,7 @@ SMBD_OBJ_SRV = smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/change_trust_pw.o smbd/fake_file.o \ smbd/quotas.o smbd/ntquotas.o $(AFS_OBJ) smbd/msdfs.o \ $(AFS_SETTOKEN_OBJ) smbd/aio.o smbd/statvfs.o \ - smbd/dmapi.o \ + smbd/dmapi.o smbd/signing.o \ smbd/file_access.o \ smbd/dnsregister.o smbd/globals.o \ $(MANGLE_OBJ) @VFS_STATIC@ @@ -741,7 +746,7 @@ SMBD_OBJ_BASE = $(PARAM_WITHOUT_REG_OBJ) $(SMBD_OBJ_SRV) $(LIBSMB_OBJ) \ $(LOCKING_OBJ) $(PASSDB_OBJ) $(PRINTING_OBJ) $(PROFILE_OBJ) \ $(LIB_OBJ) $(PRINTBACKEND_OBJ) $(OPLOCK_OBJ) \ $(NOTIFY_OBJ) $(GROUPDB_OBJ) $(AUTH_OBJ) \ - $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) \ + $(LIBMSRPC_OBJ) $(LIBMSRPC_GEN_OBJ) $(AVAHI_OBJ) \ $(LIBADS_OBJ) $(KRBCLIENT_OBJ) $(LIBADS_SERVER_OBJ) \ $(REG_FULL_OBJ) $(POPT_LIB_OBJ) $(BUILDOPT_OBJ) \ $(SMBLDAP_OBJ) $(LDB_OBJ) $(LIBNET_OBJ) @LIBWBCLIENT_STATIC@ \ @@ -826,7 +831,7 @@ PDBEDIT_OBJ = utils/pdbedit.o $(PASSWD_UTIL_OBJ) $(PARAM_OBJ) $(PASSDB_OBJ) @LIB SMBGET_OBJ = utils/smbget.o $(POPT_LIB_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBWBCLIENT_STATIC@ -DISPLAY_SEC_OBJ= lib/display_sec.o +DISPLAY_SEC_OBJ= ../libcli/security/display_sec.o RPCCLIENT_OBJ1 = rpcclient/rpcclient.o rpcclient/cmd_lsarpc.o \ rpcclient/cmd_samr.o rpcclient/cmd_spoolss.o \ @@ -1277,6 +1282,10 @@ everything:: all libtalloc libsmbclient libnetapi debug2html smbfilter talloctor .SUFFIXES: .SUFFIXES: .c .o .lo +.PHONY: showflags SHOWFLAGS + +showflags: SHOWFLAGS + SHOWFLAGS:: @echo "Using CFLAGS = $(CFLAGS)" @echo " PICFLAG = $(PICFLAG)" @@ -1385,7 +1394,7 @@ bin/smbd@EXEEXT@: $(BINARY_PREREQS) $(SMBD_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARE @echo Linking $@ @$(CC) -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \ $(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \ - $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) \ + $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) $(DNSSD_LIBS) $(AVAHI_LIBS) \ $(POPT_LIBS) @SMBD_LIBS@ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ $(WINBIND_LIBS) $(ZLIB_LIBS) @@ -1433,19 +1442,19 @@ bin/smbspool@EXEEXT@: $(BINARY_PREREQS) $(CUPS_OBJ) @BUILD_POPT@ @LIBTALLOC_SHAR @$(CC) -o $@ $(CUPS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) \ $(KRB5LIBS) $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(ZLIB_LIBS) -bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @BUILD_POPT@ +bin/mount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_MOUNT_OBJ) @echo Linking $@ - @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS) + @$(CC) -o $@ $(CIFS_MOUNT_OBJ) $(DYNEXP) $(LDFLAGS) -bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @BUILD_POPT@ +bin/umount.cifs@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UMOUNT_OBJ) @echo Linking $@ - @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) $(POPT_LIBS) + @$(CC) -o $@ $(CIFS_UMOUNT_OBJ) $(DYNEXP) $(LDFLAGS) -bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ +bin/cifs.upcall@EXEEXT@: $(BINARY_PREREQS) $(CIFS_UPCALL_OBJ) $(LIBSMBCLIENT_OBJ1) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(CIFS_UPCALL_OBJ) $(DYNEXP) $(LDFLAGS) \ -lkeyutils $(LIBS) $(LIBSMBCLIENT_OBJ1) $(KRB5LIBS) \ - $(LDAP_LIBS) $(POPT_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \ + $(LDAP_LIBS) $(LIBTALLOC_LIBS) $(WINBIND_LIBS) \ $(LIBTDB_LIBS) $(NSCD_LIBS) bin/testparm@EXEEXT@: $(BINARY_PREREQS) $(TESTPARM_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @@ -1571,7 +1580,7 @@ bin/pdbtest@EXEEXT@: $(BINARY_PREREQS) $(PDBTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SH bin/vfstest@EXEEXT@: $(BINARY_PREREQS) $(VFSTEST_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ - @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) \ + @$(CC) -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(AVAHI_LIBS) \ $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(DNSSD_LIBS) \ $(ACL_LIBS) $(LIBS) $(POPT_LIBS) $(KRB5LIBS) $(LDAP_LIBS) \ @SMBD_LIBS@ $(NSCD_LIBS) $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) \ @@ -1609,37 +1618,37 @@ bin/ldbedit: $(BINARY_PREREQS) $(LDBEDIT_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @L @echo Linking $@ @$(CC) -o $@ $(LDBEDIT_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbsearch: $(BINARY_PREREQS) $(LDBSEARCH_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBSEARCH_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbadd: $(BINARY_PREREQS) $(LDBADD_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBADD_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbmodify: $(BINARY_PREREQS) $(LDBMODIFY_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBMODIFY_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbdel: $(BINARY_PREREQS) $(LDBDEL_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) -o $@ $(LDBDEL_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/ldbrename: $(BINARY_PREREQS) $(LDBRENAME_OBJ) @BUILD_POPT@ @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @LIBWBCLIENT_SHARED@ @echo Linking $@ @$(CC) $(FLAGS) -o $@ $(LDBRENAME_OBJ) $(DYNEXP) $(LDFLAGS) \ $(LIBS) $(POPT_LIBS) $(LDAP_LIBS) \ - $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) + $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) bin/versiontest: $(BINARY_PREREQS) lib/version_test.o $(VERSION_OBJ) @echo Linking $@ @@ -2625,6 +2634,10 @@ bin/security.@SHLIBEXT@: $(BINARY_PREREQS) libgpo/gpext/security.o @echo "Building plugin $@" @$(SHLD_MODULE) libgpo/gpext/security.o +bin/dirsort.@SHLIBEXT@: $(BINARY_PREREQS) $(VFS_DIRSORT_OBJ) + @echo "Building plugin $@" + @$(SHLD_MODULE) $(VFS_DIRSORT_OBJ) + ######################################################### ## IdMap NSS plugins @@ -2648,7 +2661,7 @@ bin/ntlm_auth@EXEEXT@: $(BINARY_PREREQS) $(NTLM_AUTH_OBJ) $(PARAM_OBJ) \ bin/pam_smbpass.@SHLIBEXT@: $(BINARY_PREREQS) $(PAM_SMBPASS_OBJ) @LIBTALLOC_SHARED@ @LIBWBCLIENT_SHARED@ @LIBTDB_SHARED@ @echo "Linking shared library $@" @$(SHLD) $(LDSHFLAGS) -o $@ $(PAM_SMBPASS_OBJ) -lpam $(DYNEXP) \ - $(LIBS) $(LDAP_LIBS) $(KRB5LIBS) $(NSCD_LIBS) \ + $(LIBS) $(LDAP_LIBS) $(NSCD_LIBS) \ $(LIBTALLOC_LIBS) $(LIBTDB_LIBS) $(WINBIND_LIBS) bin/tdbbackup@EXEEXT@: $(BINARY_PREREQS) $(TDBBACKUP_OBJ) @LIBTALLOC_SHARED@ @LIBTDB_SHARED@ @@ -2893,10 +2906,10 @@ include/build_env.h: script/build_env.sh proto:: etags:: - find $(srcdir)/.. -name "*.[ch]" | xargs -n 100 etags --append + find $(srcdir)/.. -name "*.[ch]" | xargs -n 100 etags --append $(ETAGS_OPTIONS) ctags:: - ctags `find $(srcdir)/.. -name "*.[ch]" | grep -v include/proto\.h` + ctags $(CTAGS_OPTIONS) `find $(srcdir)/.. -name "*.[ch]" | grep -v include/proto\.h` realclean:: clean -rm -f config.log bin/.dummy script/findsmb script/gen-8bit-gap.sh diff --git a/source3/configure.in b/source3/configure.in index dc5850aba1..1cf8d9ca4a 100644 --- a/source3/configure.in +++ b/source3/configure.in @@ -152,13 +152,11 @@ AC_SUBST(NSCD_LIBS) # do this here since AC_CACHE_CHECK apparently sets the CFLAGS to "-g -O2" # if it has no value. This prevent *very* large debug binaries from occurring # by default. -if test "x$CFLAGS" = x; then - CFLAGS="-O" -fi if test "x$debug" = "xyes" ; then CFLAGS="${CFLAGS} -g" -else - CFLAGS="${CFLAGS} -O" +fi +if test "x$CFLAGS" = x; then + CFLAGS="-O" fi m4_include(../lib/socket_wrapper/config.m4) @@ -879,7 +877,7 @@ fi AC_CHECK_FUNCS(dirfd) if test x"$ac_cv_func_dirfd" = x"yes"; then - default_shared_modules="$default_shared_modules vfs_syncops" + default_shared_modules="$default_shared_modules vfs_syncops vfs_dirsort" fi AC_CACHE_CHECK([for struct sigevent type],samba_cv_struct_sigevent, [ @@ -5975,10 +5973,10 @@ AC_SUBST(FLAGS1) # Check if user wants DNS service discovery support AC_ARG_ENABLE(dnssd, -[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=auto)])]) +[AS_HELP_STRING([--enable-dnssd], [Enable DNS service discovery support (default=no)])]) AC_SUBST(DNSSD_LIBS) -if test x"$enable_dnssd" != x"no"; then +if test x"$enable_dnssd" == x"yes"; then have_dnssd_support=yes AC_CHECK_HEADERS(dns_sd.h) @@ -6007,6 +6005,42 @@ if test x"$enable_dnssd" != x"no"; then fi ################################################# +# Check if user wants avahi support + +AC_ARG_ENABLE(avahi, +[AS_HELP_STRING([--enable-avahi], [Enable Avahi support (default=auto)])]) + +AC_SUBST(AVAHI_LIBS) +if test x"$enable_avahi" != x"no"; then + have_avahi_support=yes + + AC_CHECK_HEADERS(avahi-common/watch.h) + if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then + have_avahi_support=no + fi + + AC_CHECK_HEADERS(avahi-client/client.h) + if test x"$ac_cv_header_avahi_common_watch_h" != x"yes"; then + have_avahi_support=no + fi + + AC_CHECK_LIB_EXT(avahi-client, AVAHI_LIBS, avahi_client_new) + if test x"$ac_cv_lib_ext_avahi_client_avahi_client_new" != x"yes"; then + have_avahi_support=no + fi + + if test x"$have_avahi_support" = x"yes"; then + AC_DEFINE(WITH_AVAHI_SUPPORT, 1, + [Whether to enable avahi support]) + AC_SUBST(AVAHI_OBJ, "lib/avahi.o smbd/avahi_register.o") + else + if test x"$enable_avahi" = x"yes"; then + AC_MSG_ERROR(avahi support not available) + fi + fi +fi + +################################################# # Check to see if we should use the included iniparser AC_ARG_WITH(included-iniparser, @@ -6213,6 +6247,7 @@ 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_MODULE(vfs_onefs, \$(VFS_ONEFS), "bin/onefs.$SHLIBEXT", VFS) SMB_MODULE(vfs_onefs_shadow_copy, \$(VFS_ONEFS_SHADOW_COPY), "bin/onefs_shadow_copy.$SHLIBEXT", VFS) +SMB_MODULE(vfs_dirsort, \$(VFS_DIRSORT_OBJ), "bin/dirsort.$SHLIBEXT", VFS) SMB_SUBSYSTEM(VFS,smbd/vfs.o) diff --git a/source3/include/async_smb.h b/source3/include/async_smb.h index 7fc4ff7d27..2ac1101a1e 100644 --- a/source3/include/async_smb.h +++ b/source3/include/async_smb.h @@ -63,6 +63,8 @@ struct cli_request { */ uint16_t mid; + uint32_t seqnum; + /** * The bytes we have to ship to the server */ diff --git a/source3/include/client.h b/source3/include/client.h index 320a90e66b..73a1d7b554 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -71,26 +71,26 @@ struct rpc_cli_transport { /** * Trigger an async read from the server. May return a short read. */ - struct async_req *(*read_send)(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv); + struct tevent_req *(*read_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv); /** * Get the result from the read_send operation. */ - NTSTATUS (*read_recv)(struct async_req *req, ssize_t *preceived); + NTSTATUS (*read_recv)(struct tevent_req *req, ssize_t *preceived); /** * Trigger an async write to the server. May return a short write. */ - struct async_req *(*write_send)(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv); + struct tevent_req *(*write_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv); /** * Get the result from the read_send operation. */ - NTSTATUS (*write_recv)(struct async_req *req, ssize_t *psent); + NTSTATUS (*write_recv)(struct tevent_req *req, ssize_t *psent); /** * This is an optimization for the SMB transport. It models the @@ -98,15 +98,15 @@ struct rpc_cli_transport { * trip. The transport implementation is free to set this to NULL, * cli_pipe.c will fall back to the explicit write/read routines. */ - struct async_req *(*trans_send)(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t data_len, - uint32_t max_rdata_len, - void *priv); + struct tevent_req *(*trans_send)(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len, + void *priv); /** * Get the result from the trans_send operation. */ - NTSTATUS (*trans_recv)(struct async_req *req, TALLOC_CTX *mem_ctx, + NTSTATUS (*trans_recv)(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len); void *priv; }; @@ -166,6 +166,13 @@ struct smb_trans_enc_state { } s; }; +struct cli_state_seqnum { + struct cli_state_seqnum *prev, *next; + uint16_t mid; + uint32_t seqnum; + bool persistent; +}; + struct cli_state { /** * A list of subsidiary connections for DFS. @@ -217,6 +224,7 @@ struct cli_state { size_t max_xmit; size_t max_mux; char *outbuf; + struct cli_state_seqnum *seqnum; char *inbuf; unsigned int bufsize; int initialised; @@ -231,7 +239,7 @@ struct cli_state { TALLOC_CTX *call_mem_ctx; #endif - smb_sign_info sign_info; + struct smb_signing_state *signing_state; struct smb_trans_enc_state *trans_enc_state; /* Setup if we're encrypting SMB's. */ diff --git a/source3/include/dbwrap.h b/source3/include/dbwrap.h index 16f10cc125..1803587c4a 100644 --- a/source3/include/dbwrap.h +++ b/source3/include/dbwrap.h @@ -54,6 +54,8 @@ struct db_context { bool persistent; }; +bool db_is_local(const char *name); + struct db_context *db_open(TALLOC_CTX *mem_ctx, const char *name, int hash_size, int tdb_flags, diff --git a/source3/include/includes.h b/source3/include/includes.h index 4bf4b5c735..c883e17713 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -598,6 +598,7 @@ struct smb_iconv_convenience *lp_iconv_convenience(void *lp_ctx); #include "messages.h" #include "locking.h" #include "smb_perfcount.h" +#include "smb_signing.h" #include "smb.h" #include "nameserv.h" #include "secrets.h" diff --git a/source3/include/proto.h b/source3/include/proto.h index 3d87f75c7b..77be0aba09 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -150,6 +150,10 @@ bool is_trusted_domain(const char* dom_name); NTSTATUS auth_winbind_init(void); +/* The following definitions come from auth/auth_wbc.c */ + +NTSTATUS auth_wbc_init(void); + /* The following definitions come from auth/pampass.c */ bool smb_pam_claim_session(char *user, char *tty, char *rhost); @@ -2410,6 +2414,10 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, int cli_set_message(char *buf,int num_words,int num_bytes,bool zero); unsigned int cli_set_timeout(struct cli_state *cli, unsigned int timeout); void cli_set_port(struct cli_state *cli, int port); +bool cli_state_seqnum_persistent(struct cli_state *cli, + uint16_t mid); +bool cli_state_seqnum_remove(struct cli_state *cli, + uint16_t mid); bool cli_receive_smb(struct cli_state *cli); ssize_t cli_receive_smb_data(struct cli_state *cli, char *buffer, size_t len); bool cli_receive_smb_readX_header(struct cli_state *cli); @@ -3181,29 +3189,34 @@ void cli_free_enc_buffer(struct cli_state *cli, char *buf); NTSTATUS cli_decrypt_message(struct cli_state *cli); NTSTATUS cli_encrypt_message(struct cli_state *cli, char *buf, char **buf_out); -/* The following definitions come from libsmb/smb_signing.c */ +/* The following definitions come from libsmb/clisigning.c */ bool cli_simple_set_signing(struct cli_state *cli, const DATA_BLOB user_session_key, const DATA_BLOB response); -bool cli_null_set_signing(struct cli_state *cli); bool cli_temp_set_signing(struct cli_state *cli); -void cli_free_signing_context(struct cli_state *cli); -void cli_calculate_sign_mac(struct cli_state *cli, char *buf); -bool cli_check_sign_mac(struct cli_state *cli, char *buf); -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid); -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid); +void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum); +bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum); bool client_is_signing_on(struct cli_state *cli); -bool srv_oplock_set_signing(bool onoff); -bool srv_check_sign_mac(const char *inbuf, bool must_be_ok); -void srv_calculate_sign_mac(char *outbuf); -void srv_defer_sign_response(uint16 mid); -void srv_cancel_sign_response(uint16 mid, bool cancel); -void srv_set_signing_negotiated(void); -bool srv_is_signing_active(void); -bool srv_is_signing_negotiated(void); -bool srv_signing_started(void); -void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response); +bool client_is_signing_allowed(struct cli_state *cli); +bool client_is_signing_mandatory(struct cli_state *cli); +void cli_set_signing_negotiated(struct cli_state *cli); + +/* The following definitions come from smbd/signing.c */ + +struct smbd_server_connection; +bool srv_check_sign_mac(struct smbd_server_connection *conn, + const char *inbuf, uint32_t *seqnum); +void srv_calculate_sign_mac(struct smbd_server_connection *conn, + char *outbuf, uint32_t seqnum); +void srv_cancel_sign_response(struct smbd_server_connection *conn); +bool srv_init_signing(struct smbd_server_connection *conn); +void srv_set_signing_negotiated(struct smbd_server_connection *conn); +bool srv_is_signing_active(struct smbd_server_connection *conn); +bool srv_is_signing_negotiated(struct smbd_server_connection *conn); +void srv_set_signing(struct smbd_server_connection *conn, + const DATA_BLOB user_session_key, + const DATA_BLOB response); /* The following definitions come from libsmb/smbdes.c */ @@ -3779,6 +3792,8 @@ bool send_mailslot(bool unique, const char *mailslot,char *buf, size_t len, /* The following definitions come from nmbd/nmbd_processlogon.c */ +bool initialize_nmbd_proxy_logon(void); + void process_logon_packet(struct packet_struct *p, char *buf,int len, const char *mailslot); @@ -4345,7 +4360,7 @@ const char *lp_printcapname(void); bool lp_disable_spoolss( void ); void lp_set_spoolss_state( uint32 state ); uint32 lp_get_spoolss_state( void ); -bool lp_use_sendfile(int snum); +bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state); void set_use_sendfile(int snum, bool val); void set_store_dos_attributes(int snum, bool val); void lp_set_mangling_method(const char *new_method); @@ -4828,7 +4843,7 @@ WERROR add_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const cha REGISTRY_VALUE* get_printer_data( NT_PRINTER_INFO_LEVEL_2 *p2, const char *key, const char *value ); WERROR mod_a_printer(NT_PRINTER_INFO_LEVEL *printer, uint32 level); bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level); -bool del_driver_init(char *drivername); +bool del_driver_init(const char *drivername); WERROR save_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level, uint8 *data, uint32 data_len); WERROR get_a_printer( Printer_entry *print_hnd, NT_PRINTER_INFO_LEVEL **pp_printer, @@ -4840,8 +4855,8 @@ WERROR get_a_printer_search( Printer_entry *print_hnd, const char *sharename); uint32 free_a_printer(NT_PRINTER_INFO_LEVEL **pp_printer, uint32 level); uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); -WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring drivername, const char *architecture, uint32 version); +WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level, + const char *drivername, const char *architecture, uint32_t version); uint32 free_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level); bool printer_driver_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info_3 ); bool printer_driver_files_in_use ( NT_PRINTER_DRIVER_INFO_LEVEL_3 *info ); @@ -5241,22 +5256,22 @@ NTSTATUS rpccli_netlogon_set_trust_password(struct rpc_pipe_client *cli, /* The following definitions come from rpc_client/cli_pipe.c */ -struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - uint8_t op_num, - prs_struct *req_data); -NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t op_num, + prs_struct *req_data); +NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, prs_struct *reply_pdu); NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, uint8 op_num, prs_struct *in_data, prs_struct *out_data); -struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - struct cli_pipe_auth_data *auth); -NTSTATUS rpc_pipe_bind_recv(struct async_req *req); +struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth); +NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req); NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, struct cli_pipe_auth_data *auth); unsigned int rpccli_set_timeout(struct rpc_pipe_client *cli, @@ -5678,10 +5693,8 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli, bool smb_io_time(const char *desc, NTTIME *nttime, prs_struct *ps, int depth); bool smb_io_system_time(const char *desc, prs_struct *ps, int depth, SYSTEMTIME *systime); bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime); -bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth); bool smb_io_uuid(const char *desc, struct GUID *uuid, prs_struct *ps, int depth); -void init_unistr(UNISTR *str, const char *buf); void init_unistr2(UNISTR2 *str, const char *buf, enum unistr2_term_codes flags); /* The following definitions come from rpc_parse/parse_prs.c */ @@ -5803,11 +5816,6 @@ bool smb_io_rpc_auth_schannel_chk(const char *desc, int auth_len, RPC_AUTH_SCHANNEL_CHK * chk, prs_struct *ps, int depth); -/* The following definitions come from rpc_parse/parse_sec.c */ - -bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth); -bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth); - /* The following definitions come from rpc_server/srv_eventlog_lib.c */ TDB_CONTEXT *elog_init_tdb( char *tdbfilename ); @@ -5898,6 +5906,8 @@ NTSTATUS np_read_recv(struct tevent_req *req, ssize_t *nread, /* The following definitions come from rpc_server/srv_samr_util.c */ +void copy_id18_to_sam_passwd(struct samu *to, + struct samr_UserInfo18 *from); void copy_id20_to_sam_passwd(struct samu *to, struct samr_UserInfo20 *from); void copy_id21_to_sam_passwd(const char *log_prefix, @@ -5905,8 +5915,12 @@ void copy_id21_to_sam_passwd(const char *log_prefix, struct samr_UserInfo21 *from); void copy_id23_to_sam_passwd(struct samu *to, struct samr_UserInfo23 *from); +void copy_id24_to_sam_passwd(struct samu *to, + struct samr_UserInfo24 *from); void copy_id25_to_sam_passwd(struct samu *to, struct samr_UserInfo25 *from); +void copy_id26_to_sam_passwd(struct samu *to, + struct samr_UserInfo26 *from); /* The following definitions come from rpc_server/srv_spoolss_nt.c */ @@ -5925,8 +5939,9 @@ void reset_all_printerdata(struct messaging_context *msg, bool convert_devicemode(const char *printername, const struct spoolss_DeviceMode *devmode, NT_DEVICEMODE **pp_nt_devmode); -WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, - uint32 type, uint8 *data, int real_len ); +WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer, + const char *key, const char *value, + uint32_t type, uint8_t *data, int real_len); void spoolss_notify_server_name(int snum, struct spoolss_Notify *data, print_queue_struct *queue, @@ -6713,7 +6728,9 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname); void smbd_setup_sig_term_handler(void); void smbd_setup_sig_hup_handler(void); -bool srv_send_smb(int fd, char *buffer, bool do_encrypt, +bool srv_send_smb(int fd, char *buffer, + bool no_signing, uint32_t seqnum, + bool do_encrypt, struct smb_perfcount_data *pcd); int srv_set_message(char *buf, int num_words, @@ -7210,6 +7227,16 @@ NTSTATUS idmap_sid_to_gid(const char *domname, DOM_SID *sid, gid_t *gid); NTSTATUS nss_info_template_init( void ); +/* The following definitions come from lib/avahi.c */ + +struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, + struct tevent_context *ev); + +/* The following definitions come from smbd/avahi_register.c */ + +void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + uint16_t port); + /* Misc protos */ #endif /* _PROTO_H_ */ diff --git a/source3/include/rpc_dce.h b/source3/include/rpc_dce.h index 580b14f1d8..ca58040757 100644 --- a/source3/include/rpc_dce.h +++ b/source3/include/rpc_dce.h @@ -81,16 +81,6 @@ enum RPC_PKT_TYPE { #define RPC_PIPE_AUTH_SEAL_LEVEL 0x6 #endif -#define DCERPC_FAULT_OP_RNG_ERROR 0x1c010002 -#define DCERPC_FAULT_UNK_IF 0x1c010003 -#define DCERPC_FAULT_INVALID_TAG 0x1c000006 -#define DCERPC_FAULT_CONTEXT_MISMATCH 0x1c00001a -#define DCERPC_FAULT_OTHER 0x00000001 -#define DCERPC_FAULT_ACCESS_DENIED 0x00000005 -#define DCERPC_FAULT_CANT_PERFORM 0x000006d8 -#define DCERPC_FAULT_NDR 0x000006f7 - - /* Netlogon schannel auth type and level */ #define SCHANNEL_SIGN_SIGNATURE { 0x77, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00 } #define SCHANNEL_SEAL_SIGNATURE { 0x77, 0x00, 0x7a, 0x00, 0xff, 0xff, 0x00, 0x00 } diff --git a/source3/include/smb.h b/source3/include/smb.h index 281a218256..01e6ddf64c 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -252,6 +252,8 @@ struct id_map { #include "librpc/gen_ndr/drsuapi.h" #include "librpc/gen_ndr/drsblobs.h" #include "librpc/gen_ndr/spoolss.h" +#include "librpc/gen_ndr/dcerpc.h" +#include "librpc/gen_ndr/ndr_dcerpc.h" struct lsa_dom_info { bool valid; @@ -621,6 +623,7 @@ struct smb_request { uint16 flags2; uint16 smbpid; uint16 mid; + uint32_t seqnum; uint16 vuid; uint16 tid; uint8 wct; @@ -722,6 +725,7 @@ struct pending_message_list { struct timeval request_time; /* When was this first issued? */ struct timed_event *te; struct smb_perfcount_data pcd; + uint32_t seqnum; bool encrypted; DATA_BLOB buf; DATA_BLOB private_data; @@ -1847,21 +1851,6 @@ struct ip_service { /* Special name type used to cause a _kerberos DNS lookup. */ #define KDC_NAME_TYPE 0xDCDC -/* Used by the SMB signing functions. */ - -typedef struct smb_sign_info { - void (*sign_outgoing_message)(char *outbuf, struct smb_sign_info *si); - bool (*check_incoming_message)(const char *inbuf, struct smb_sign_info *si, bool must_be_ok); - void (*free_signing_context)(struct smb_sign_info *si); - void *signing_context; - - bool negotiated_smb_signing; - bool allow_smb_signing; - bool doing_signing; - bool mandatory_signing; - bool seen_valid; /* Have I ever seen a validly signed packet? */ -} smb_sign_info; - struct ea_struct { uint8 flags; char *name; diff --git a/source3/include/smb_perfcount.h b/source3/include/smb_perfcount.h index 01a539d508..9c83147d04 100644 --- a/source3/include/smb_perfcount.h +++ b/source3/include/smb_perfcount.h @@ -37,8 +37,6 @@ struct smb_perfcount_handlers { uint64_t in_bytes); void (*perfcount_set_msglen_out) (struct smb_perfcount_data *pcd, uint64_t out_bytes); - void (*perfcount_set_client) (struct smb_perfcount_data *pcd, uid_t uid, - const char *user, const char *domain); void (*perfcount_copy_context) (struct smb_perfcount_data *pcd, struct smb_perfcount_data *new_pcd); void (*perfcount_defer_op) (struct smb_perfcount_data *pcd, @@ -88,12 +86,6 @@ void smb_init_perfcount_data(struct smb_perfcount_data *pcd); (_pcd_)->handlers->perfcount_set_msglen_out((_pcd_), (_out_));\ } while (0) -#define SMB_PERFCOUNT_SET_CLIENT(_pcd_,_uid_, _user_, _domain_) \ - do {if((_pcd_) && (_pcd_)->handlers) \ - (_pcd_)->handlers->perfcount_set_client((_pcd_), (_uid_), \ - (_user_), (_domain_)); \ - } while (0) - #define SMB_PERFCOUNT_COPY_CONTEXT(_pcd_, _new_pcd_) \ do {if((_pcd_) && (_pcd_)->handlers) \ (_pcd_)->handlers->perfcount_copy_context((_pcd_), (_new_pcd_)); \ diff --git a/source3/include/smb_signing.h b/source3/include/smb_signing.h new file mode 100644 index 0000000000..770c40cb35 --- /dev/null +++ b/source3/include/smb_signing.h @@ -0,0 +1,46 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 + Copyright (C) Stefan Metzmacher 2009 + + 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/>. +*/ + +#ifndef _SMB_SIGNING_H_ +#define _SMB_SIGNING_H_ + +struct smb_signing_state; + +struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx, + bool allowed, + bool mandatory); +uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway); +void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway); +void smb_signing_sign_pdu(struct smb_signing_state *si, + uint8_t *outbuf, uint32_t seqnum); +bool smb_signing_check_pdu(struct smb_signing_state *si, + const uint8_t *inbuf, uint32_t seqnum); +bool smb_signing_set_bsrspyl(struct smb_signing_state *si); +bool smb_signing_activate(struct smb_signing_state *si, + const DATA_BLOB user_session_key, + const DATA_BLOB response); +bool smb_signing_is_active(struct smb_signing_state *si); +bool smb_signing_is_allowed(struct smb_signing_state *si); +bool smb_signing_is_mandatory(struct smb_signing_state *si); +bool smb_signing_set_negotiated(struct smb_signing_state *si); +bool smb_signing_is_negotiated(struct smb_signing_state *si); + +#endif /* _SMB_SIGNING_H_ */ diff --git a/source3/lib/avahi.c b/source3/lib/avahi.c new file mode 100644 index 0000000000..269b329e64 --- /dev/null +++ b/source3/lib/avahi.c @@ -0,0 +1,275 @@ +/* + Unix SMB/CIFS implementation. + Connect avahi to lib/tevents + Copyright (C) Volker Lendecke 2009 + + 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 <avahi-common/watch.h> + +struct avahi_poll_context { + struct tevent_context *ev; + AvahiWatch **watches; + AvahiTimeout **timeouts; +}; + +struct AvahiWatch { + struct avahi_poll_context *ctx; + struct tevent_fd *fde; + int fd; + AvahiWatchEvent latest_event; + AvahiWatchCallback callback; + void *userdata; +}; + +struct AvahiTimeout { + struct avahi_poll_context *ctx; + struct tevent_timer *te; + AvahiTimeoutCallback callback; + void *userdata; +}; + +static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event) +{ + return ((event & AVAHI_WATCH_IN) ? TEVENT_FD_READ : 0) + | ((event & AVAHI_WATCH_OUT) ? TEVENT_FD_WRITE : 0); +} + +static void avahi_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *private_data); + +static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd, + AvahiWatchEvent event, + AvahiWatchCallback callback, + void *userdata) +{ + struct avahi_poll_context *ctx = talloc_get_type_abort( + api->userdata, struct avahi_poll_context); + int num_watches = talloc_array_length(ctx->watches); + AvahiWatch **tmp, *watch_ctx; + + tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1); + if (tmp == NULL) { + return NULL; + } + ctx->watches = tmp; + + watch_ctx = talloc(tmp, AvahiWatch); + if (watch_ctx == NULL) { + goto fail; + } + ctx->watches[num_watches] = watch_ctx; + + watch_ctx->ctx = ctx; + watch_ctx->fde = tevent_add_fd(ctx->ev, watch_ctx, fd, + avahi_flags_map_to_tevent(event), + avahi_fd_handler, watch_ctx); + if (watch_ctx->fde == NULL) { + goto fail; + } + watch_ctx->callback = callback; + watch_ctx->userdata = userdata; + return watch_ctx; + + fail: + TALLOC_FREE(watch_ctx); + ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *, + num_watches); + return NULL; +} + +static void avahi_fd_handler(struct tevent_context *ev, + struct tevent_fd *fde, uint16_t flags, + void *private_data) +{ + AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch); + + watch_ctx->latest_event = + ((flags & TEVENT_FD_READ) ? AVAHI_WATCH_IN : 0) + | ((flags & TEVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0); + + watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event, + watch_ctx->userdata); +} + +static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event) +{ + tevent_fd_set_flags(w->fde, avahi_flags_map_to_tevent(event)); +} + +static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w) +{ + return w->latest_event; +} + +static void avahi_watch_free(AvahiWatch *w) +{ + int i, num_watches; + AvahiWatch **watches = w->ctx->watches; + struct avahi_poll_context *ctx; + + num_watches = talloc_array_length(watches); + + for (i=0; i<num_watches; i++) { + if (w == watches[i]) { + break; + } + } + if (i == num_watches) { + return; + } + ctx = w->ctx; + TALLOC_FREE(w); + memmove(&watches[i], &watches[i+1], + sizeof(*watches) * (num_watches - i - 1)); + ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *, + num_watches - 1); +} + +static void avahi_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data); + +static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api, + const struct timeval *tv, + AvahiTimeoutCallback callback, + void *userdata) +{ + struct avahi_poll_context *ctx = talloc_get_type_abort( + api->userdata, struct avahi_poll_context); + int num_timeouts = talloc_array_length(ctx->timeouts); + AvahiTimeout **tmp, *timeout_ctx; + + tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *, + num_timeouts + 1); + if (tmp == NULL) { + return NULL; + } + ctx->timeouts = tmp; + + timeout_ctx = talloc(tmp, AvahiTimeout); + if (timeout_ctx == NULL) { + goto fail; + } + ctx->timeouts[num_timeouts] = timeout_ctx; + + timeout_ctx->ctx = ctx; + if (tv == NULL) { + timeout_ctx->te = NULL; + } else { + timeout_ctx->te = tevent_add_timer(ctx->ev, timeout_ctx, + *tv, avahi_timeout_handler, + timeout_ctx); + if (timeout_ctx->te == NULL) { + goto fail; + } + } + timeout_ctx->callback = callback; + timeout_ctx->userdata = userdata; + return timeout_ctx; + + fail: + TALLOC_FREE(timeout_ctx); + ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *, + num_timeouts); + return NULL; +} + +static void avahi_timeout_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + AvahiTimeout *timeout_ctx = talloc_get_type_abort( + private_data, AvahiTimeout); + + TALLOC_FREE(timeout_ctx->te); + timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata); +} + +static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv) +{ + TALLOC_FREE(t->te); + + if (tv == NULL) { + /* + * Disable this timer + */ + return; + } + + t->te = tevent_add_timer(t->ctx->ev, t, *tv, avahi_timeout_handler, t); + /* + * No failure mode defined here + */ + SMB_ASSERT(t->te != NULL); +} + +static void avahi_timeout_free(AvahiTimeout *t) +{ + int i, num_timeouts; + AvahiTimeout **timeouts = t->ctx->timeouts; + struct avahi_poll_context *ctx; + + num_timeouts = talloc_array_length(timeouts); + + for (i=0; i<num_timeouts; i++) { + if (t == timeouts[i]) { + break; + } + } + if (i == num_timeouts) { + return; + } + ctx = t->ctx; + TALLOC_FREE(t); + memmove(&timeouts[i], &timeouts[i+1], + sizeof(*timeouts) * (num_timeouts - i - 1)); + ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *, + num_timeouts - 1); +} + +struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx, + struct tevent_context *ev) +{ + struct AvahiPoll *result; + struct avahi_poll_context *ctx; + + result = talloc(mem_ctx, struct AvahiPoll); + if (result == NULL) { + return result; + } + ctx = talloc_zero(result, struct avahi_poll_context); + if (ctx == NULL) { + TALLOC_FREE(result); + return NULL; + } + ctx->ev = ev; + + result->watch_new = avahi_watch_new; + result->watch_update = avahi_watch_update; + result->watch_get_events = avahi_watch_get_events; + result->watch_free = avahi_watch_free; + result->timeout_new = avahi_timeout_new; + result->timeout_update = avahi_timeout_update; + result->timeout_free = avahi_timeout_free; + result->userdata = ctx; + + return result; +} diff --git a/source3/lib/dbwrap.c b/source3/lib/dbwrap.c index 5e7ce6099f..67c08a6085 100644 --- a/source3/lib/dbwrap.c +++ b/source3/lib/dbwrap.c @@ -65,6 +65,33 @@ static int dbwrap_fallback_parse_record(struct db_context *db, TDB_DATA key, return res; } +bool db_is_local(const char *name) +{ +#ifdef CLUSTER_SUPPORT + const char *sockname = lp_ctdbd_socket(); + + if(!sockname || !*sockname) { + sockname = CTDB_PATH; + } + + if (lp_clustering() && socket_exist(sockname)) { + const char *partname; + /* ctdb only wants the file part of the name */ + partname = strrchr(name, '/'); + if (partname) { + partname++; + } else { + partname = name; + } + /* allow ctdb for individual databases to be disabled */ + if (lp_parm_bool(-1, "ctdb", partname, True)) { + return false; + } + } +#endif + return true; +} + /** * open a database */ diff --git a/source3/lib/netapi/cm.c b/source3/lib/netapi/cm.c index b676ae63dd..d28b2b2126 100644 --- a/source3/lib/netapi/cm.c +++ b/source3/lib/netapi/cm.c @@ -57,6 +57,11 @@ static WERROR libnetapi_open_ipc_connection(struct libnetapi_ctx *ctx, false, false, PROTOCOL_NT1, 0, 0x20); + if (cli_ipc) { + cli_set_username(cli_ipc, ctx->username); + cli_set_password(cli_ipc, ctx->password); + cli_set_domain(cli_ipc, ctx->workgroup); + } TALLOC_FREE(auth_info); if (!cli_ipc) { diff --git a/source3/lib/netapi/group.c b/source3/lib/netapi/group.c index 189902a78e..c09632a857 100644 --- a/source3/lib/netapi/group.c +++ b/source3/lib/netapi/group.c @@ -1276,6 +1276,7 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx, *r->out.buffer = NULL; *r->out.entries_read = 0; + *r->out.total_entries = 0; switch (r->in.level) { case 0: @@ -1364,13 +1365,8 @@ WERROR NetGroupGetUsers_r(struct libnetapi_ctx *ctx, } } - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } + *r->out.entries_read = entries_read; + *r->out.total_entries = entries_read; werr = WERR_OK; diff --git a/source3/lib/netapi/user.c b/source3/lib/netapi/user.c index 8cc65a6e9e..1cbb883169 100644 --- a/source3/lib/netapi/user.c +++ b/source3/lib/netapi/user.c @@ -1497,6 +1497,9 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx, NTSTATUS status = NT_STATUS_OK; WERROR werr; + WERROR werr_tmp; + + *r->out.entries_read = 0; ZERO_STRUCT(connect_handle); ZERO_STRUCT(domain_handle); @@ -1540,15 +1543,18 @@ WERROR NetQueryDisplayInformation_r(struct libnetapi_ctx *ctx, &total_size, &returned_size, &info); - if (!NT_STATUS_IS_OK(status)) { - werr = ntstatus_to_werror(status); + werr = ntstatus_to_werror(status); + if (NT_STATUS_IS_ERR(status)) { goto done; } - werr = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info, - r->in.level, - r->out.entries_read, - r->out.buffer); + werr_tmp = convert_samr_dispinfo_to_NET_DISPLAY(ctx, &info, + r->in.level, + r->out.entries_read, + r->out.buffer); + if (!W_ERROR_IS_OK(werr_tmp)) { + werr = werr_tmp; + } done: /* if last query */ if (NT_STATUS_IS_OK(status) || @@ -2806,6 +2812,7 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx, *r->out.buffer = NULL; *r->out.entries_read = 0; + *r->out.total_entries = 0; switch (r->in.level) { case 0: @@ -2899,12 +2906,8 @@ WERROR NetUserGetGroups_r(struct libnetapi_ctx *ctx, } } - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } + *r->out.entries_read = entries_read; + *r->out.total_entries = entries_read; done: if (ctx->disable_policy_handle_cache) { @@ -3242,6 +3245,7 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, *r->out.buffer = NULL; *r->out.entries_read = 0; + *r->out.total_entries = 0; switch (r->in.level) { case 0: @@ -3402,12 +3406,8 @@ WERROR NetUserGetLocalGroups_r(struct libnetapi_ctx *ctx, } } - if (r->out.entries_read) { - *r->out.entries_read = entries_read; - } - if (r->out.total_entries) { - *r->out.total_entries = entries_read; - } + *r->out.entries_read = entries_read; + *r->out.total_entries = entries_read; done: if (ctx->disable_policy_handle_cache) { diff --git a/source3/lib/util_file.c b/source3/lib/util_file.c index c5a9b7c29a..50ff844762 100644 --- a/source3/lib/util_file.c +++ b/source3/lib/util_file.c @@ -39,7 +39,7 @@ static char *file_pload(const char *syscmd, size_t *size) total = 0; while ((n = read(fd, buf, sizeof(buf))) > 0) { - p = (char *)SMB_REALLOC(p, total + n + 1); + p = talloc_realloc(NULL, p, char, total + n + 1); if (!p) { DEBUG(0,("file_pload: failed to expand buffer!\n")); close(fd); diff --git a/source3/lib/wbclient.c b/source3/lib/wbclient.c index 3cf992c7de..c22e168454 100644 --- a/source3/lib/wbclient.c +++ b/source3/lib/wbclient.c @@ -449,8 +449,8 @@ static void wb_open_pipe_connect_nonpriv_done(struct tevent_req *subreq) ZERO_STRUCT(state->wb_req); state->wb_req.cmd = WINBINDD_INTERFACE_VERSION; - subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, - &state->wb_req); + subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue, + state->wb_ctx->fd, &state->wb_req); if (tevent_req_nomem(subreq, req)) { return; } @@ -480,8 +480,8 @@ static void wb_open_pipe_ping_done(struct tevent_req *subreq) state->wb_req.cmd = WINBINDD_PRIV_PIPE_DIR; - subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, - &state->wb_req); + subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue, + state->wb_ctx->fd, &state->wb_req); if (tevent_req_nomem(subreq, req)) { return; } @@ -673,8 +673,8 @@ static void wb_trans_connect_done(struct tevent_req *subreq) return; } - subreq = wb_int_trans_send(state, state->ev, NULL, state->wb_ctx->fd, - state->wb_req); + subreq = wb_int_trans_send(state, state->ev, state->wb_ctx->queue, + state->wb_ctx->fd, state->wb_req); if (tevent_req_nomem(subreq, req)) { return; } diff --git a/source3/libads/kerberos.c b/source3/libads/kerberos.c index 56d7b061a1..52cb975a6c 100644 --- a/source3/libads/kerberos.c +++ b/source3/libads/kerberos.c @@ -511,13 +511,13 @@ char *kerberos_get_default_realm_from_ccache( void ) out: - if (princ) { - krb5_free_principal(ctx, princ); - } - if (cc) { - krb5_cc_close(ctx, cc); - } if (ctx) { + if (princ) { + krb5_free_principal(ctx, princ); + } + if (cc) { + krb5_cc_close(ctx, cc); + } krb5_free_context(ctx); } diff --git a/source3/libnet/libnet_samsync.c b/source3/libnet/libnet_samsync.c index 73d4439743..0c00b8518a 100644 --- a/source3/libnet/libnet_samsync.c +++ b/source3/libnet/libnet_samsync.c @@ -422,9 +422,6 @@ static NTSTATUS libnet_samsync_delta(TALLOC_CTX *mem_ctx, TALLOC_FREE(delta_enum_array); - /* Increment sync_context */ - sync_context += 1; - } while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES)); out: diff --git a/source3/libsmb/async_smb.c b/source3/libsmb/async_smb.c index e579d1c9f0..86fd5c8bef 100644 --- a/source3/libsmb/async_smb.c +++ b/source3/libsmb/async_smb.c @@ -550,7 +550,7 @@ void cli_chain_uncork(struct cli_state *cli) _smb_setlen_large(((char *)req->outbuf), smblen); } - cli_calculate_sign_mac(cli, (char *)req->outbuf); + cli_calculate_sign_mac(cli, (char *)req->outbuf, &req->seqnum); if (cli_encryption_on(cli)) { NTSTATUS status; @@ -811,9 +811,16 @@ NTSTATUS cli_pull_reply(struct async_req *req, */ -static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) +static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu, + struct cli_request **_req, + uint16_t *_mid) { NTSTATUS status; + struct cli_request *req = NULL; + uint16_t mid; + + *_req = NULL; + *_mid = 0; if ((IVAL(pdu, 4) != 0x424d53ff) /* 0xFF"SMB" */ && (SVAL(pdu, 4) != 0x45ff)) /* 0xFF"E" */ { @@ -846,11 +853,27 @@ static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) } } - if (!cli_check_sign_mac(cli, pdu)) { + mid = SVAL(pdu, smb_mid); + + for (req = cli->outstanding_requests; req; req = req->next) { + if (req->mid == mid) { + break; + } + } + + if (!req) { + /* oplock breaks are not signed */ + goto done; + } + + if (!cli_check_sign_mac(cli, pdu, req->seqnum+1)) { DEBUG(10, ("cli_check_sign_mac failed\n")); return NT_STATUS_ACCESS_DENIED; } +done: + *_req = req; + *_mid = mid; return NT_STATUS_OK; } @@ -861,9 +884,9 @@ static NTSTATUS validate_smb_crypto(struct cli_state *cli, char *pdu) static void handle_incoming_pdu(struct cli_state *cli) { - struct cli_request *req; + struct cli_request *req, *next; uint16_t mid; - size_t raw_pdu_len, buf_len, pdu_len, rest_len; + size_t raw_pdu_len, buf_len, rest_len; char *pdu; int i; NTSTATUS status; @@ -923,23 +946,13 @@ static void handle_incoming_pdu(struct cli_state *cli) } } - status = validate_smb_crypto(cli, pdu); + status = validate_smb_crypto(cli, pdu, &req, &mid); if (!NT_STATUS_IS_OK(status)) { goto invalidate_requests; } - mid = SVAL(pdu, smb_mid); - DEBUG(10, ("handle_incoming_pdu: got mid %d\n", mid)); - for (req = cli->outstanding_requests; req; req = req->next) { - if (req->mid == mid) { - break; - } - } - - pdu_len = smb_len(pdu) + 4; - if (req == NULL) { DEBUG(3, ("Request for mid %d not found, dumping PDU\n", mid)); @@ -978,8 +991,11 @@ static void handle_incoming_pdu(struct cli_state *cli) DEBUG(10, ("handle_incoming_pdu: Aborting with %s\n", nt_errstr(status))); - for (req = cli->outstanding_requests; req; req = req->next) { - async_req_nterror(req->async[0], status); + for (req = cli->outstanding_requests; req; req = next) { + next = req->next; + if (req->num_async) { + async_req_nterror(req->async[0], status); + } } return; } diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ebb01c44a6..aa1ca595a7 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -505,11 +505,7 @@ static NTSTATUS cli_session_setup_nt1(struct cli_state *cli, const char *user, ok = cli_simple_set_signing(cli, session_key, nt_response); #endif if (ok) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli, cli->outbuf); - - if (!cli_check_sign_mac(cli, cli->inbuf)) { + if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { result = NT_STATUS_ACCESS_DENIED; goto end; } @@ -747,11 +743,7 @@ static ADS_STATUS cli_session_setup_kerberos(struct cli_state *cli, const char * if (cli_simple_set_signing( cli, session_key_krb5, data_blob_null)) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli, cli->outbuf); - - if (!cli_check_sign_mac(cli, cli->inbuf)) { + if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { nt_status = NT_STATUS_ACCESS_DENIED; goto nt_error; } @@ -873,11 +865,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use if (cli_simple_set_signing( cli, ntlmssp_state->session_key, data_blob_null)) { - /* 'resign' the last message, so we get the right sequence numbers - for checking the first reply from the server */ - cli_calculate_sign_mac(cli, cli->outbuf); - - if (!cli_check_sign_mac(cli, cli->inbuf)) { + if (!cli_check_sign_mac(cli, cli->inbuf, 1)) { nt_status = NT_STATUS_ACCESS_DENIED; } } @@ -1540,13 +1528,16 @@ NTSTATUS cli_negprot_recv(struct async_req *req) cli->protocol = prots[protnum].prot; - if ((cli->protocol < PROTOCOL_NT1) && cli->sign_info.mandatory_signing) { + if ((cli->protocol < PROTOCOL_NT1) && + client_is_signing_mandatory(cli)) { DEBUG(0,("cli_negprot: SMB signing is mandatory and the selected protocol level doesn't support it.\n")); return NT_STATUS_ACCESS_DENIED; } if (cli->protocol >= PROTOCOL_NT1) { struct timespec ts; + bool negotiated_smb_signing = false; + /* NT protocol */ cli->sec_mode = CVAL(vwv + 1, 0); cli->max_mux = SVAL(vwv + 1, 1); @@ -1579,22 +1570,24 @@ NTSTATUS cli_negprot_recv(struct async_req *req) if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_REQUIRED) { /* Fail if server says signing is mandatory and we don't want to support it. */ - if (!cli->sign_info.allow_smb_signing) { + if (!client_is_signing_allowed(cli)) { DEBUG(0,("cli_negprot: SMB signing is mandatory and we have disabled it.\n")); return NT_STATUS_ACCESS_DENIED; } - cli->sign_info.negotiated_smb_signing = True; - cli->sign_info.mandatory_signing = True; - } else if (cli->sign_info.mandatory_signing && cli->sign_info.allow_smb_signing) { + negotiated_smb_signing = true; + } else if (client_is_signing_mandatory(cli) && client_is_signing_allowed(cli)) { /* Fail if client says signing is mandatory and the server doesn't support it. */ if (!(cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED)) { DEBUG(1,("cli_negprot: SMB signing is mandatory and the server doesn't support it.\n")); return NT_STATUS_ACCESS_DENIED; } - cli->sign_info.negotiated_smb_signing = True; - cli->sign_info.mandatory_signing = True; + negotiated_smb_signing = true; } else if (cli->sec_mode & NEGOTIATE_SECURITY_SIGNATURES_ENABLED) { - cli->sign_info.negotiated_smb_signing = True; + negotiated_smb_signing = true; + } + + if (negotiated_smb_signing) { + cli_set_signing_negotiated(cli); } if (cli->capabilities & (CAP_LARGE_READX|CAP_LARGE_WRITEX)) { @@ -1841,10 +1834,9 @@ static NTSTATUS open_smb_socket(const struct sockaddr_storage *pss, tevent_req_set_callback(r445, smb_sock_connected, fd445); tevent_req_set_callback(r139, smb_sock_connected, fd139); - while ((fd139->fd == -1) - && tevent_req_is_in_progress(r139) - && (fd445->fd == -1) - && tevent_req_is_in_progress(r445)) { + while ((fd445->fd == -1) && (fd139->fd == -1) + && (tevent_req_is_in_progress(r139) + || tevent_req_is_in_progress(r445))) { event_loop_once(ev); } diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index c1ba4e5c4f..6186387076 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -135,6 +135,79 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) return len; } +static bool cli_state_set_seqnum(struct cli_state *cli, uint16_t mid, uint32_t seqnum) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + c->seqnum = seqnum; + return true; + } + } + + c = talloc_zero(cli, struct cli_state_seqnum); + if (!c) { + return false; + } + + c->mid = mid; + c->seqnum = seqnum; + c->persistent = false; + DLIST_ADD_END(cli->seqnum, c, struct cli_state_seqnum *); + + return true; +} + +bool cli_state_seqnum_persistent(struct cli_state *cli, + uint16_t mid) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + c->persistent = true; + return true; + } + } + + return false; +} + +bool cli_state_seqnum_remove(struct cli_state *cli, + uint16_t mid) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + DLIST_REMOVE(cli->seqnum, c); + TALLOC_FREE(c); + return true; + } + } + + return false; +} + +static uint32_t cli_state_get_seqnum(struct cli_state *cli, uint16_t mid) +{ + struct cli_state_seqnum *c; + + for (c = cli->seqnum; c; c = c->next) { + if (c->mid == mid) { + uint32_t seqnum = c->seqnum; + if (!c->persistent) { + DLIST_REMOVE(cli->seqnum, c); + TALLOC_FREE(c); + } + return seqnum; + } + } + + return 0; +} + /**************************************************************************** Recv an smb. ****************************************************************************/ @@ -142,6 +215,8 @@ static ssize_t client_receive_smb(struct cli_state *cli, size_t maxlen) bool cli_receive_smb(struct cli_state *cli) { ssize_t len; + uint16_t mid; + uint32_t seqnum; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) @@ -177,7 +252,10 @@ bool cli_receive_smb(struct cli_state *cli) return false; } - if (!cli_check_sign_mac(cli, cli->inbuf)) { + mid = SVAL(cli->inbuf,smb_mid); + seqnum = cli_state_get_seqnum(cli, mid); + + if (!cli_check_sign_mac(cli, cli->inbuf, seqnum+1)) { /* * If we get a signature failure in sessionsetup, then * the server sometimes just reflects the sent signature @@ -264,12 +342,20 @@ bool cli_send_smb(struct cli_state *cli) ssize_t ret; char *buf_out = cli->outbuf; bool enc_on = cli_encryption_on(cli); + uint32_t seqnum; /* fd == -1 causes segfaults -- Tom (tom@ninja.nl) */ if (cli->fd == -1) return false; - cli_calculate_sign_mac(cli, cli->outbuf); + cli_calculate_sign_mac(cli, cli->outbuf, &seqnum); + + if (!cli_state_set_seqnum(cli, cli->mid, seqnum)) { + DEBUG(0,("Failed to store mid[%u]/seqnum[%u]\n", + (unsigned int)cli->mid, + (unsigned int)seqnum)); + return false; + } if (enc_on) { NTSTATUS status = cli_encrypt_message(cli, cli->outbuf, @@ -506,6 +592,7 @@ struct cli_state *cli_initialise_ex(int signing_state) cli->bufsize = CLI_BUFFER_SIZE+4; cli->max_xmit = cli->bufsize; cli->outbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); + cli->seqnum = 0; cli->inbuf = (char *)SMB_MALLOC(cli->bufsize+SAFETY_MARGIN); cli->oplock_handler = cli_oplock_ack; cli->case_sensitive = false; @@ -556,9 +643,12 @@ struct cli_state *cli_initialise_ex(int signing_state) #endif /* initialise signing */ - cli->sign_info.allow_smb_signing = allow_smb_signing; - cli->sign_info.mandatory_signing = mandatory_signing; - cli_null_set_signing(cli); + cli->signing_state = smb_signing_init(cli, + allow_smb_signing, + mandatory_signing); + if (!cli->signing_state) { + goto error; + } cli->initialised = 1; @@ -641,7 +731,6 @@ void cli_shutdown(struct cli_state *cli) SAFE_FREE(cli->outbuf); SAFE_FREE(cli->inbuf); - cli_free_signing_context(cli); data_blob_free(&cli->secblob); data_blob_free(&cli->user_session_key); @@ -740,7 +829,6 @@ static void cli_echo_recv_helper(struct async_req *req) cli_req->data.echo.num_echos -= 1; if (cli_req->data.echo.num_echos == 0) { - client_set_trans_sign_state_off(cli_req->cli, cli_req->mid); async_req_done(req); return; } @@ -782,8 +870,6 @@ struct async_req *cli_echo_send(TALLOC_CTX *mem_ctx, struct event_context *ev, } req = talloc_get_type_abort(result->private_data, struct cli_request); - client_set_trans_sign_state_on(cli, req->mid); - req->data.echo.num_echos = num_echos; req->data.echo.data.data = talloc_move(req, &data_copy); req->data.echo.data.length = data.length; diff --git a/source3/libsmb/clikrb5.c b/source3/libsmb/clikrb5.c index 168ca63303..4ab31374e2 100644 --- a/source3/libsmb/clikrb5.c +++ b/source3/libsmb/clikrb5.c @@ -878,24 +878,30 @@ failed: bool get_krb5_smb_session_key(krb5_context context, krb5_auth_context auth_context, DATA_BLOB *session_key, bool remote) { - krb5_keyblock *skey; - krb5_error_code err; - bool ret = False; + krb5_keyblock *skey = NULL; + krb5_error_code err = 0; + bool ret = false; - if (remote) + if (remote) { err = krb5_auth_con_getremotesubkey(context, auth_context, &skey); - else + } else { err = krb5_auth_con_getlocalsubkey(context, auth_context, &skey); - if (err == 0 && skey != NULL) { - DEBUG(10, ("Got KRB5 session key of length %d\n", (int)KRB5_KEY_LENGTH(skey))); - *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); - dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + } - ret = True; + if (err || skey == NULL) { + DEBUG(10, ("KRB5 error getting session key %d\n", err)); + goto done; + } + DEBUG(10, ("Got KRB5 session key of length %d\n", (int)KRB5_KEY_LENGTH(skey))); + *session_key = data_blob(KRB5_KEY_DATA(skey), KRB5_KEY_LENGTH(skey)); + dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length); + + ret = true; + + done: + if (skey) { krb5_free_keyblock(context, skey); - } else { - DEBUG(10, ("KRB5 error getting session key %d\n", err)); } return ret; diff --git a/source3/libsmb/clisigning.c b/source3/libsmb/clisigning.c new file mode 100644 index 0000000000..0d0e926e6c --- /dev/null +++ b/source3/libsmb/clisigning.c @@ -0,0 +1,87 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 + Copyright (C) Stefan Metzmacher 2009 + + 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" + +bool cli_simple_set_signing(struct cli_state *cli, + const DATA_BLOB user_session_key, + const DATA_BLOB response) +{ + bool ok; + + ok = smb_signing_activate(cli->signing_state, + user_session_key, + response); + if (!ok) { + return false; + } + + cli->readbraw_supported = false; + cli->writebraw_supported = false; + + return true; +} + +bool cli_temp_set_signing(struct cli_state *cli) +{ + return smb_signing_set_bsrspyl(cli->signing_state); +} + +void cli_calculate_sign_mac(struct cli_state *cli, char *buf, uint32_t *seqnum) +{ + *seqnum = smb_signing_next_seqnum(cli->signing_state, false); + smb_signing_sign_pdu(cli->signing_state, (uint8_t *)buf, *seqnum); +} + +bool cli_check_sign_mac(struct cli_state *cli, const char *buf, uint32_t seqnum) +{ + bool ok; + + ok = smb_signing_check_pdu(cli->signing_state, + (const uint8_t *)buf, + seqnum); + + if (!ok) { + return false; + } + + return true; +} + +void cli_set_signing_negotiated(struct cli_state *cli) +{ + smb_signing_set_negotiated(cli->signing_state); +} + +bool client_is_signing_on(struct cli_state *cli) +{ + return smb_signing_is_active(cli->signing_state); +} + +bool client_is_signing_allowed(struct cli_state *cli) +{ + return smb_signing_is_allowed(cli->signing_state); +} + +bool client_is_signing_mandatory(struct cli_state *cli) +{ + return smb_signing_is_mandatory(cli->signing_state); +} diff --git a/source3/libsmb/clitrans.c b/source3/libsmb/clitrans.c index 0266c0307e..c566972b21 100644 --- a/source3/libsmb/clitrans.c +++ b/source3/libsmb/clitrans.c @@ -94,14 +94,12 @@ bool cli_send_trans(struct cli_state *cli, int trans, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); + cli_state_seqnum_persistent(cli, mid); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); + cli_state_seqnum_remove(cli, mid); return(False); } @@ -137,12 +135,11 @@ bool cli_send_trans(struct cli_state *cli, int trans, show_msg(cli->outbuf); - client_set_trans_sign_state_off(cli, mid); cli->mid = mid; if (!cli_send_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } - client_set_trans_sign_state_on(cli, mid); tot_data += this_ldata; tot_param += this_lparam; @@ -165,10 +162,14 @@ bool cli_receive_trans(struct cli_state *cli,int trans, unsigned int this_data,this_param; NTSTATUS status; bool ret = False; + uint16_t mid; *data_len = *param_len = 0; + mid = SVAL(cli->inbuf,smb_mid); + if (!cli_receive_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } @@ -179,6 +180,7 @@ bool cli_receive_trans(struct cli_state *cli,int trans, DEBUG(0,("Expected %s response, got command 0x%02x\n", trans==SMBtrans?"SMBtrans":"SMBtrans2", CVAL(cli->inbuf,smb_com))); + cli_state_seqnum_remove(cli, mid); return False; } @@ -331,6 +333,8 @@ bool cli_receive_trans(struct cli_state *cli,int trans, out: + cli_state_seqnum_remove(cli, mid); + if (ret) { /* Ensure the last 2 bytes of param and data are 2 null * bytes. These are malloc'ed, but not included in any @@ -344,7 +348,6 @@ bool cli_receive_trans(struct cli_state *cli,int trans, } } - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -412,14 +415,12 @@ bool cli_send_nt_trans(struct cli_state *cli, return False; } - /* Note we're in a trans state. Save the sequence - * numbers for replies. */ - client_set_trans_sign_state_on(cli, mid); + cli_state_seqnum_persistent(cli, mid); if (this_ldata < ldata || this_lparam < lparam) { /* receive interim response */ if (!cli_receive_smb(cli) || cli_is_error(cli)) { - client_set_trans_sign_state_off(cli, mid); + cli_state_seqnum_remove(cli, mid); return(False); } @@ -454,12 +455,11 @@ bool cli_send_nt_trans(struct cli_state *cli, show_msg(cli->outbuf); - client_set_trans_sign_state_off(cli, mid); cli->mid = mid; if (!cli_send_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } - client_set_trans_sign_state_on(cli, mid); tot_data += this_ldata; tot_param += this_lparam; @@ -483,10 +483,14 @@ bool cli_receive_nt_trans(struct cli_state *cli, uint8 eclass; uint32 ecode; bool ret = False; + uint16_t mid; *data_len = *param_len = 0; + mid = SVAL(cli->inbuf,smb_mid); + if (!cli_receive_smb(cli)) { + cli_state_seqnum_remove(cli, mid); return False; } @@ -496,6 +500,7 @@ bool cli_receive_nt_trans(struct cli_state *cli, if (CVAL(cli->inbuf,smb_com) != SMBnttrans) { DEBUG(0,("Expected SMBnttrans response, got command 0x%02x\n", CVAL(cli->inbuf,smb_com))); + cli_state_seqnum_remove(cli, mid); return(False); } @@ -669,6 +674,8 @@ bool cli_receive_nt_trans(struct cli_state *cli, out: + cli_state_seqnum_remove(cli, mid); + if (ret) { /* Ensure the last 2 bytes of param and data are 2 null * bytes. These are malloc'ed, but not included in any @@ -682,7 +689,6 @@ bool cli_receive_nt_trans(struct cli_state *cli, } } - client_set_trans_sign_state_off(cli, SVAL(cli->inbuf,smb_mid)); return ret; } @@ -696,6 +702,7 @@ struct cli_trans_state { struct event_context *ev; uint8_t cmd; uint16_t mid; + uint32_t seqnum; const char *pipe_name; uint16_t fid; uint16_t function; @@ -919,6 +926,7 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, cli_req = talloc_get_type_abort(result->private_data, struct cli_request); state->mid = cli_req->mid; + state->seqnum = cli_req->seqnum; } else { uint16_t num_bytes = talloc_get_size(bytes); /* @@ -939,12 +947,10 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, cli_req->recv_helper.fn = cli_trans_recv_helper; cli_req->recv_helper.priv = state; cli_req->mid = state->mid; - client_set_trans_sign_state_off(state->cli, state->mid); cli_chain_uncork(state->cli); + state->seqnum = cli_req->seqnum; } - client_set_trans_sign_state_on(state->cli, state->mid); - fail: TALLOC_FREE(frame); return result; @@ -953,6 +959,8 @@ static struct async_req *cli_ship_trans(TALLOC_CTX *mem_ctx, static void cli_trans_ship_rest(struct async_req *req, struct cli_trans_state *state) { + struct cli_request *cli_req; + state->secondary_request_ctx = talloc_new(state); if (state->secondary_request_ctx == NULL) { async_req_nterror(req, NT_STATUS_NO_MEMORY); @@ -961,14 +969,19 @@ static void cli_trans_ship_rest(struct async_req *req, while ((state->param_sent < state->num_param) || (state->data_sent < state->num_data)) { - struct async_req *cli_req; + struct async_req *subreq; - cli_req = cli_ship_trans(state->secondary_request_ctx, state); - if (cli_req == NULL) { + subreq = cli_ship_trans(state->secondary_request_ctx, state); + if (subreq == NULL) { async_req_nterror(req, NT_STATUS_NO_MEMORY); return; } } + + cli_req = talloc_get_type_abort(req->private_data, + struct cli_request); + + cli_req->seqnum = state->seqnum; } static NTSTATUS cli_pull_trans(struct async_req *req, @@ -1174,7 +1187,6 @@ static void cli_trans_recv_helper(struct async_req *req) if ((state->rparam.total == state->rparam.received) && (state->rdata.total == state->rdata.received)) { - client_set_trans_sign_state_off(state->cli, state->mid); async_req_done(req); } } diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c index 3491544175..1064a63d97 100644 --- a/source3/libsmb/dsgetdcname.c +++ b/source3/libsmb/dsgetdcname.c @@ -311,7 +311,7 @@ static uint32_t get_cldap_reply_server_flags(struct netlogon_samlogon_response * /**************************************************************** ****************************************************************/ -#define RETURN_ON_FALSE(x) if (!x) return false; +#define RETURN_ON_FALSE(x) if (!(x)) return false; static bool check_cldap_reply_required_flags(uint32_t ret_flags, uint32_t req_flags) diff --git a/source3/libsmb/libsmb_dir.c b/source3/libsmb/libsmb_dir.c index 2255db6617..219bbe64e1 100644 --- a/source3/libsmb/libsmb_dir.c +++ b/source3/libsmb/libsmb_dir.c @@ -1171,7 +1171,8 @@ SMBC_mkdir_ctx(SMBCCTX *context, srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); - TALLOC_FREE(frame); + errno = ENOENT; + TALLOC_FREE(frame); return -1; } /*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/ @@ -1278,6 +1279,7 @@ SMBC_rmdir_ctx(SMBCCTX *context, srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -1561,6 +1563,7 @@ SMBC_chmod_ctx(SMBCCTX *context, srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -1753,6 +1756,7 @@ SMBC_unlink_ctx(SMBCCTX *context, srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -1927,6 +1931,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, path1, &targetcli1, &targetpath1)) { d_printf("Could not resolve %s\n", path1); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -1944,6 +1949,7 @@ SMBC_rename_ctx(SMBCCTX *ocontext, path2, &targetcli2, &targetpath2)) { d_printf("Could not resolve %s\n", path2); + errno = ENOENT; TALLOC_FREE(frame); return -1; } diff --git a/source3/libsmb/libsmb_file.c b/source3/libsmb/libsmb_file.c index 06e41ad21e..aa02807092 100644 --- a/source3/libsmb/libsmb_file.c +++ b/source3/libsmb/libsmb_file.c @@ -119,6 +119,7 @@ SMBC_open_ctx(SMBCCTX *context, srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; SAFE_FREE(file); TALLOC_FREE(frame); return NULL; @@ -300,6 +301,7 @@ SMBC_read_ctx(SMBCCTX *context, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -390,6 +392,7 @@ SMBC_write_ctx(SMBCCTX *context, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -466,6 +469,7 @@ SMBC_close_ctx(SMBCCTX *context, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -549,6 +553,7 @@ SMBC_getatr(SMBCCTX * context, srv->cli, fixedpath, &targetcli, &targetpath)) { d_printf("Couldn't resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return False; } @@ -762,6 +767,7 @@ SMBC_lseek_ctx(SMBCCTX *context, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } @@ -854,6 +860,7 @@ SMBC_ftruncate_ctx(SMBCCTX *context, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } diff --git a/source3/libsmb/libsmb_stat.c b/source3/libsmb/libsmb_stat.c index dc904d2753..c2806daddb 100644 --- a/source3/libsmb/libsmb_stat.c +++ b/source3/libsmb/libsmb_stat.c @@ -261,6 +261,7 @@ SMBC_fstat_ctx(SMBCCTX *context, file->srv->cli, path, &targetcli, &targetpath)) { d_printf("Could not resolve %s\n", path); + errno = ENOENT; TALLOC_FREE(frame); return -1; } diff --git a/source3/libsmb/smb_seal.c b/source3/libsmb/smb_seal.c index 795c8bc14c..2f7305c5b6 100644 --- a/source3/libsmb/smb_seal.c +++ b/source3/libsmb/smb_seal.c @@ -136,7 +136,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, smb_set_enclen(buf_out, smb_len(buf) + NTLMSSP_SIG_SIZE, enc_ctx_num); - sig = data_blob(NULL, NTLMSSP_SIG_SIZE); + ZERO_STRUCT(sig); status = ntlmssp_seal_packet(ntlmssp_state, (unsigned char *)buf_out + 8 + NTLMSSP_SIG_SIZE, /* 4 byte len + 0xFF 'S' <enc> <ctx> */ @@ -153,6 +153,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, /* First 16 data bytes are signature for SSPI compatibility. */ memcpy(buf_out + 8, sig.data, NTLMSSP_SIG_SIZE); + data_blob_free(&sig); *ppbuf_out = buf_out; return NT_STATUS_OK; } diff --git a/source3/libsmb/smb_signing.c b/source3/libsmb/smb_signing.c index a3ed0e7572..32d2883965 100644 --- a/source3/libsmb/smb_signing.c +++ b/source3/libsmb/smb_signing.c @@ -1,8 +1,9 @@ -/* +/* Unix SMB/CIFS implementation. SMB Signing Code Copyright (C) Jeremy Allison 2003. Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 + Copyright (C) Stefan Metzmacher 2009 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 @@ -20,260 +21,89 @@ #include "includes.h" -/* Lookup a packet's MID (multiplex id) and figure out it's sequence number */ -struct outstanding_packet_lookup { - struct outstanding_packet_lookup *prev, *next; - uint16 mid; - uint32 reply_seq_num; - bool can_delete; /* Set to False in trans state. */ -}; +/* Used by the SMB signing functions. */ -struct smb_basic_signing_context { - DATA_BLOB mac_key; - uint32 send_seq_num; - struct outstanding_packet_lookup *outstanding_packet_list; -}; - -static bool store_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 reply_seq_num) -{ - struct outstanding_packet_lookup *t; +struct smb_signing_state { + /* is signing localy allowed */ + bool allowed; - /* Ensure we only add a mid once. */ - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - return False; - } - } + /* is signing localy mandatory */ + bool mandatory; - t = SMB_XMALLOC_P(struct outstanding_packet_lookup); - ZERO_STRUCTP(t); + /* is signing negotiated by the peer */ + bool negotiated; - t->mid = mid; - t->reply_seq_num = reply_seq_num; - t->can_delete = True; + /* send BSRSPYL signatures */ + bool bsrspyl; - /* - * Add to the *start* of the list not the end of the list. - * This ensures that the *last* send sequence with this mid - * is returned by preference. - * This can happen if the mid wraps and one of the early - * mid numbers didn't get a reply and is still lurking on - * the list. JRA. Found by Fran Fabrizio <fran@cis.uab.edu>. - */ + bool active; /* Have I ever seen a validly signed packet? */ - DLIST_ADD(*list, t); - DEBUG(10,("store_sequence_for_reply: stored seq = %u mid = %u\n", - (unsigned int)reply_seq_num, (unsigned int)mid )); - return True; -} + /* mac_key.length > 0 means signing is started */ + DATA_BLOB mac_key; -static bool get_sequence_for_reply(struct outstanding_packet_lookup **list, - uint16 mid, uint32 *reply_seq_num) -{ - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - *reply_seq_num = t->reply_seq_num; - DEBUG(10,("get_sequence_for_reply: found seq = %u mid = %u\n", - (unsigned int)t->reply_seq_num, (unsigned int)t->mid )); - if (t->can_delete) { - DLIST_REMOVE(*list, t); - SAFE_FREE(t); - } - return True; - } - } - return False; -} + /* the next expected seqnum */ + uint32_t seqnum; +}; -static bool set_sequence_can_delete_flag(struct outstanding_packet_lookup **list, uint16 mid, bool can_delete_entry) +static void smb_signing_reset_info(struct smb_signing_state *si) { - struct outstanding_packet_lookup *t; - - for (t = *list; t; t = t->next) { - if (t->mid == mid) { - t->can_delete = can_delete_entry; - return True; - } - } - return False; + si->active = false; + si->bsrspyl = false; + data_blob_free(&si->mac_key); + si->seqnum = 0; } -/*********************************************************** - SMB signing - Common code before we set a new signing implementation -************************************************************/ - -static bool cli_set_smb_signing_common(struct cli_state *cli) +struct smb_signing_state *smb_signing_init(TALLOC_CTX *mem_ctx, + bool allowed, + bool mandatory) { - if (!cli->sign_info.allow_smb_signing) { - return False; - } + struct smb_signing_state *si; - if (!cli->sign_info.negotiated_smb_signing - && !cli->sign_info.mandatory_signing) { - return False; + si = talloc_zero(mem_ctx, struct smb_signing_state); + if (si == NULL) { + return NULL; } - if (cli->sign_info.doing_signing) { - return False; + if (mandatory) { + allowed = true; } - if (cli->sign_info.free_signing_context) - cli->sign_info.free_signing_context(&cli->sign_info); - - /* These calls are INCOMPATIBLE with SMB signing */ - cli->readbraw_supported = False; - cli->writebraw_supported = False; - - return True; -} - -/*********************************************************** - SMB signing - Common code for 'real' implementations -************************************************************/ - -static bool set_smb_signing_real_common(struct smb_sign_info *si) -{ - if (si->mandatory_signing) { - DEBUG(5, ("Mandatory SMB signing enabled!\n")); - } - - si->doing_signing = True; - DEBUG(5, ("SMB signing enabled!\n")); - - return True; -} - -static void mark_packet_signed(char *outbuf) -{ - uint16 flags2; - flags2 = SVAL(outbuf,smb_flg2); - flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; - SSVAL(outbuf,smb_flg2, flags2); -} - -/*********************************************************** - SMB signing - NULL implementation - calculate a MAC to send. -************************************************************/ - -static void null_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - /* we can't zero out the sig, as we might be trying to send a - session request - which is NBT-level, not SMB level and doesn't - have the field */ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - check a MAC sent by server. -************************************************************/ - -static bool null_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) -{ - return True; -} - -/*********************************************************** - SMB signing - NULL implementation - free signing context -************************************************************/ - -static void null_free_signing_context(struct smb_sign_info *si) -{ - return; -} - -/** - SMB signing - NULL implementation - setup the MAC key. - - @note Used as an initialisation only - it will not correctly - shut down a real signing mechanism -*/ - -static bool null_set_signing(struct smb_sign_info *si) -{ - si->signing_context = NULL; - - si->sign_outgoing_message = null_sign_outgoing_message; - si->check_incoming_message = null_check_incoming_message; - si->free_signing_context = null_free_signing_context; - - return True; -} - -/** - * Free the signing context - */ - -static void free_signing_context(struct smb_sign_info *si) -{ - if (si->free_signing_context) { - si->free_signing_context(si); - si->signing_context = NULL; - } + si->allowed = allowed; + si->mandatory = mandatory; - null_set_signing(si); + return si; } - -static bool signing_good(const char *inbuf, struct smb_sign_info *si, - bool good, uint32 seq, bool must_be_ok) +static bool smb_signing_good(struct smb_signing_state *si, + bool good, uint32_t seq) { if (good) { - - if (!si->doing_signing) { - si->doing_signing = True; + if (!si->active) { + si->active = true; } + return true; + } - if (!si->seen_valid) { - si->seen_valid = True; - } - - } else { - if (!si->mandatory_signing && !si->seen_valid) { - - if (!must_be_ok) { - return True; - } - /* Non-mandatory signing - just turn off if this is the first bad packet.. */ - DEBUG(5, ("srv_check_incoming_message: signing negotiated but not required and peer\n" - "isn't sending correct signatures. Turning off.\n")); - si->negotiated_smb_signing = False; - si->allow_smb_signing = False; - si->doing_signing = False; - free_signing_context(si); - return True; - } else if (!must_be_ok) { - /* This packet is known to be unsigned */ - return True; - } else { - /* Mandatory signing or bad packet after signing started - fail and disconnect. */ - if (seq) - DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); - return False; - } + if (!si->mandatory && !si->active) { + /* Non-mandatory signing - just turn off if this is the first bad packet.. */ + DEBUG(5, ("smb_signing_good: signing negotiated but not required and peer\n" + "isn't sending correct signatures. Turning off.\n")); + smb_signing_reset_info(si); + return true; } - return True; -} -/*********************************************************** - SMB signing - Simple implementation - calculate a MAC on the packet -************************************************************/ + /* Mandatory signing or bad packet after signing started - fail and disconnect. */ + DEBUG(0, ("smb_signing_good: BAD SIG: seq %u\n", (unsigned int)seq)); + return false; +} -static void simple_packet_signature(struct smb_basic_signing_context *data, - const uchar *buf, uint32 seq_number, - unsigned char calc_md5_mac[16]) +static void smb_signing_md5(const DATA_BLOB *mac_key, + const uint8_t *buf, uint32_t seq_number, + uint8_t calc_md5_mac[16]) { const size_t offset_end_of_sig = (smb_ss_field + 8); - unsigned char sequence_buf[8]; + uint8_t sequence_buf[8]; struct MD5Context md5_ctx; -#if 0 - /* JRA - apparently this is incorrect. */ - unsigned char key_buf[16]; -#endif /* * Firstly put the sequence number into the first 4 bytes. @@ -282,7 +112,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, * We do this here, to avoid modifying the packet. */ - DEBUG(10,("simple_packet_signature: sequence number %u\n", seq_number )); + DEBUG(10,("smb_signing_md5: sequence number %u\n", seq_number )); SIVAL(sequence_buf, 0, seq_number); SIVAL(sequence_buf, 4, 0); @@ -295,17 +125,7 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Init(&md5_ctx); /* intialise with the key */ - MD5Update(&md5_ctx, data->mac_key.data, data->mac_key.length); -#if 0 - /* JRA - apparently this is incorrect. */ - /* NB. When making and verifying SMB signatures, Windows apparently - zero-pads the key to 128 bits if it isn't long enough. - From Nalin Dahyabhai <nalin@redhat.com> */ - if (data->mac_key.length < sizeof(key_buf)) { - memset(key_buf, 0, sizeof(key_buf)); - MD5Update(&md5_ctx, key_buf, sizeof(key_buf) - data->mac_key.length); - } -#endif + MD5Update(&md5_ctx, mac_key->data, mac_key->length); /* copy in the first bit of the SMB header */ MD5Update(&md5_ctx, buf + 4, smb_ss_field - 4); @@ -317,690 +137,234 @@ static void simple_packet_signature(struct smb_basic_signing_context *data, MD5Update(&md5_ctx, buf + offset_end_of_sig, smb_len(buf) - (offset_end_of_sig - 4)); - /* calculate the MD5 sig */ + /* calculate the MD5 sig */ MD5Final(calc_md5_mac, &md5_ctx); } - -/*********************************************************** - SMB signing - Client implementation - send the MAC. -************************************************************/ - -static void client_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) - return; - - /* JRA Paranioa test - we should be able to get rid of this... */ - if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("client_sign_outgoing_message: Logic error. Can't check signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); - abort(); - } - - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - simple_packet_signature(data, (const unsigned char *)outbuf, - data->send_seq_num, calc_md5_mac); - - DEBUG(10, ("client_sign_outgoing_message: sent SMB signature of\n")); - dump_data(10, calc_md5_mac, 8); - - memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); - -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote server actually verifies signatures...*/ - - /* Instead of re-introducing the trans_info_conect we - used to have here, we use the fact that during a - SMBtrans/SMBtrans2/SMBnttrans send that the mid stays - constant. This means that calling store_sequence_for_reply() - will return False for all trans secondaries, as the mid is already - on the stored sequence list. As the send_seqence_number must - remain constant for all primary+secondary trans sends, we - only increment the send sequence number when we successfully - add a new entry to the outstanding sequence list. This means - I can isolate the fix here rather than re-adding the trans - signing on/off calls in libsmb/clitrans2.c JRA. - */ - - if (store_sequence_for_reply(&data->outstanding_packet_list, SVAL(outbuf,smb_mid), data->send_seq_num + 1)) { - data->send_seq_num += 2; - } -} - -/*********************************************************** - SMB signing - Client implementation - check a MAC sent by server. -************************************************************/ - -static bool client_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) +uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway) { - bool good; - uint32 reply_seq_number; - unsigned char calc_md5_mac[16]; - unsigned char *server_sent_mac; - - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; + uint32_t seqnum; - if (!si->doing_signing) - return True; - - if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("client_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); - return False; + if (si->mac_key.length == 0) { + return 0; } - if (!get_sequence_for_reply(&data->outstanding_packet_list, SVAL(inbuf, smb_mid), &reply_seq_number)) { - DEBUG(1, ("client_check_incoming_message: received message " - "with mid %u with no matching send record.\n", (unsigned int)SVAL(inbuf, smb_mid) )); - return False; - } - - simple_packet_signature(data, (const unsigned char *)inbuf, - reply_seq_number, calc_md5_mac); - - server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; - good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); - - if (!good) { - DEBUG(5, ("client_check_incoming_message: BAD SIG: wanted SMB signature of\n")); - dump_data(5, calc_md5_mac, 8); - - DEBUG(5, ("client_check_incoming_message: BAD SIG: got SMB signature of\n")); - dump_data(5, server_sent_mac, 8); -#if 1 /* JRATEST */ - { - int i; - for (i = -5; i < 5; i++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number+i, calc_md5_mac); - if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("client_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number+i, reply_seq_number )); - break; - } - } - } -#endif /* JRATEST */ - + seqnum = si->seqnum; + if (oneway) { + si->seqnum += 1; } else { - DEBUG(10, ("client_check_incoming_message: seq %u: got good SMB signature of\n", (unsigned int)reply_seq_number)); - dump_data(10, server_sent_mac, 8); - } - return signing_good(inbuf, si, good, reply_seq_number, must_be_ok); -} - -/*********************************************************** - SMB signing - Simple implementation - free signing context -************************************************************/ - -static void simple_free_signing_context(struct smb_sign_info *si) -{ - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - struct outstanding_packet_lookup *list; - struct outstanding_packet_lookup *next; - - for (list = data->outstanding_packet_list; list; list = next) { - next = list->next; - DLIST_REMOVE(data->outstanding_packet_list, list); - SAFE_FREE(list); + si->seqnum += 2; } - data_blob_free(&data->mac_key); - - SAFE_FREE(si->signing_context); - - return; + return seqnum; } -/*********************************************************** - SMB signing - Simple implementation - setup the MAC key. -************************************************************/ - -bool cli_simple_set_signing(struct cli_state *cli, - const DATA_BLOB user_session_key, - const DATA_BLOB response) +void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway) { - struct smb_basic_signing_context *data; - - if (!user_session_key.length) - return False; - - if (!cli_set_smb_signing_common(cli)) { - return False; - } - - if (!set_smb_signing_real_common(&cli->sign_info)) { - return False; + if (si->mac_key.length == 0) { + return; } - data = SMB_XMALLOC_P(struct smb_basic_signing_context); - memset(data, '\0', sizeof(*data)); - - cli->sign_info.signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); - - DEBUG(10, ("cli_simple_set_signing: user_session_key\n")); - dump_data(10, user_session_key.data, user_session_key.length); - - if (response.length) { - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); - DEBUG(10, ("cli_simple_set_signing: response_data\n")); - dump_data(10, response.data, response.length); + if (oneway) { + si->seqnum -= 1; } else { - DEBUG(10, ("cli_simple_set_signing: NULL response_data\n")); + si->seqnum -= 2; } - - dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); - - /* Initialise the sequence number */ - data->send_seq_num = 0; - - /* Initialise the list of outstanding packets */ - data->outstanding_packet_list = NULL; - - cli->sign_info.sign_outgoing_message = client_sign_outgoing_message; - cli->sign_info.check_incoming_message = client_check_incoming_message; - cli->sign_info.free_signing_context = simple_free_signing_context; - - return True; } -/*********************************************************** - SMB signing - TEMP implementation - calculate a MAC to send. -************************************************************/ - -static void temp_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) +void smb_signing_sign_pdu(struct smb_signing_state *si, + uint8_t *outbuf, uint32_t seqnum) { - /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - /* I wonder what BSRSPYL stands for - but this is what MS - actually sends! */ - memcpy(&outbuf[smb_ss_field], "BSRSPYL ", 8); - return; -} - -/*********************************************************** - SMB signing - TEMP implementation - check a MAC sent by server. -************************************************************/ + uint8_t calc_md5_mac[16]; + uint16_t flags2; -static bool temp_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, bool foo) -{ - return True; -} - -/*********************************************************** - SMB signing - TEMP implementation - free signing context -************************************************************/ - -static void temp_free_signing_context(struct smb_sign_info *si) -{ - return; -} - -/*********************************************************** - SMB signing - NULL implementation - setup the MAC key. -************************************************************/ - -bool cli_null_set_signing(struct cli_state *cli) -{ - return null_set_signing(&cli->sign_info); -} - -/*********************************************************** - SMB signing - temp implementation - setup the MAC key. -************************************************************/ - -bool cli_temp_set_signing(struct cli_state *cli) -{ - if (!cli_set_smb_signing_common(cli)) { - return False; - } - - cli->sign_info.signing_context = NULL; - - cli->sign_info.sign_outgoing_message = temp_sign_outgoing_message; - cli->sign_info.check_incoming_message = temp_check_incoming_message; - cli->sign_info.free_signing_context = temp_free_signing_context; - - return True; -} - -void cli_free_signing_context(struct cli_state *cli) -{ - free_signing_context(&cli->sign_info); -} - -/** - * Sign a packet with the current mechanism - */ - -void cli_calculate_sign_mac(struct cli_state *cli, char *buf) -{ - cli->sign_info.sign_outgoing_message(buf, &cli->sign_info); -} - -/** - * Check a packet with the current mechanism - * @return False if we had an established signing connection - * which had a bad checksum, True otherwise. - */ - -bool cli_check_sign_mac(struct cli_state *cli, char *buf) -{ - if (!cli->sign_info.check_incoming_message(buf, &cli->sign_info, True)) { - free_signing_context(&cli->sign_info); - return False; - } - return True; -} - -/*********************************************************** - Enter trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_on(struct cli_state *cli, uint16 mid) -{ - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, False)) { - return False; - } - - return True; -} - -/*********************************************************** - Leave trans/trans2/nttrans state. -************************************************************/ - -bool client_set_trans_sign_state_off(struct cli_state *cli, uint16 mid) -{ - uint32 reply_seq_num; - struct smb_sign_info *si = &cli->sign_info; - struct smb_basic_signing_context *data = (struct smb_basic_signing_context *)si->signing_context; - - if (!si->doing_signing) { - return True; - } - - if (!data) { - return False; - } - - if (!set_sequence_can_delete_flag(&data->outstanding_packet_list, mid, True)) { - return False; - } - - /* Now delete the stored mid entry. */ - if (!get_sequence_for_reply(&data->outstanding_packet_list, mid, &reply_seq_num)) { - return False; - } - - return True; -} - -/*********************************************************** - Is client signing on ? -************************************************************/ - -bool client_is_signing_on(struct cli_state *cli) -{ - struct smb_sign_info *si = &cli->sign_info; - return si->doing_signing; -} - -/*********************************************************** - SMB signing - Server implementation - send the MAC. -************************************************************/ - -static void srv_sign_outgoing_message(char *outbuf, struct smb_sign_info *si) -{ - unsigned char calc_md5_mac[16]; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - uint32 send_seq_number = data->send_seq_num-1; - uint16 mid; - - if (!si->doing_signing) { - return; + if (si->mac_key.length == 0) { + if (!si->bsrspyl) { + return; + } } /* JRA Paranioa test - we should be able to get rid of this... */ if (smb_len(outbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_sign_outgoing_message: Logic error. Can't send signature on short packet! smb_len = %u\n", - smb_len(outbuf) )); + DEBUG(1,("smb_signing_sign_pdu: Logic error. " + "Can't check signature on short packet! smb_len = %u\n", + smb_len(outbuf))); abort(); } /* mark the packet as signed - BEFORE we sign it...*/ - mark_packet_signed(outbuf); - - mid = SVAL(outbuf, smb_mid); - - /* See if this is a reply for a deferred packet. */ - get_sequence_for_reply(&data->outstanding_packet_list, mid, &send_seq_number); + flags2 = SVAL(outbuf,smb_flg2); + flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES; + SSVAL(outbuf, smb_flg2, flags2); - simple_packet_signature(data, (const unsigned char *)outbuf, send_seq_number, calc_md5_mac); + if (si->bsrspyl) { + /* I wonder what BSRSPYL stands for - but this is what MS + actually sends! */ + memcpy(calc_md5_mac, "BSRSPYL ", 8); + } else { + smb_signing_md5(&si->mac_key, outbuf, + seqnum, calc_md5_mac); + } - DEBUG(10, ("srv_sign_outgoing_message: seq %u: sent SMB signature of\n", (unsigned int)send_seq_number)); + DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n")); dump_data(10, calc_md5_mac, 8); memcpy(&outbuf[smb_ss_field], calc_md5_mac, 8); -/* cli->outbuf[smb_ss_field+2]=0; - Uncomment this to test if the remote client actually verifies signatures...*/ +/* outbuf[smb_ss_field+2]=0; + Uncomment this to test if the remote server actually verifies signatures...*/ } -/*********************************************************** - SMB signing - Server implementation - check a MAC sent by server. -************************************************************/ - -static bool srv_check_incoming_message(const char *inbuf, - struct smb_sign_info *si, - bool must_be_ok) +bool smb_signing_check_pdu(struct smb_signing_state *si, + const uint8_t *inbuf, uint32_t seqnum) { bool good; - struct smb_basic_signing_context *data = - (struct smb_basic_signing_context *)si->signing_context; - uint32 reply_seq_number = data->send_seq_num; - uint32 saved_seq; - unsigned char calc_md5_mac[16]; - unsigned char *server_sent_mac; + uint8_t calc_md5_mac[16]; + const uint8_t *reply_sent_mac; - if (!si->doing_signing) - return True; + if (si->mac_key.length == 0) { + return true; + } if (smb_len(inbuf) < (smb_ss_field + 8 - 4)) { - DEBUG(1, ("srv_check_incoming_message: Can't check signature on short packet! smb_len = %u\n", smb_len(inbuf))); + DEBUG(1,("smb_signing_check_pdu: Can't check signature " + "on short packet! smb_len = %u\n", + smb_len(inbuf))); return False; } - /* We always increment the sequence number. */ - data->send_seq_num += 2; - - saved_seq = reply_seq_number; - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); + smb_signing_md5(&si->mac_key, inbuf, + seqnum, calc_md5_mac); - server_sent_mac = (unsigned char *)&inbuf[smb_ss_field]; - good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0); + reply_sent_mac = &inbuf[smb_ss_field]; + good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0); if (!good) { + int i; + const int sign_range = 5; - if (saved_seq) { - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u wanted SMB signature of\n", - (unsigned int)saved_seq)); - dump_data(5, calc_md5_mac, 8); - - DEBUG(0, ("srv_check_incoming_message: BAD SIG: seq %u got SMB signature of\n", - (unsigned int)reply_seq_number)); - dump_data(5, server_sent_mac, 8); - } + DEBUG(5, ("smb_signing_check_pdu: BAD SIG: wanted SMB signature of\n")); + dump_data(5, calc_md5_mac, 8); -#if 1 /* JRATEST */ - { - int i; - reply_seq_number -= 5; - for (i = 0; i < 10; i++, reply_seq_number++) { - simple_packet_signature(data, (const unsigned char *)inbuf, reply_seq_number, calc_md5_mac); - if (memcmp(server_sent_mac, calc_md5_mac, 8) == 0) { - DEBUG(0,("srv_check_incoming_message: out of seq. seq num %u matches. \ -We were expecting seq %u\n", reply_seq_number, saved_seq )); - break; - } + DEBUG(5, ("smb_signing_check_pdu: BAD SIG: got SMB signature of\n")); + dump_data(5, reply_sent_mac, 8); + + for (i = -sign_range; i < sign_range; i++) { + smb_signing_md5(&si->mac_key, inbuf, + seqnum+i, calc_md5_mac); + if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) { + DEBUG(0,("smb_signing_check_pdu: " + "out of seq. seq num %u matches. " + "We were expecting seq %u\n", + (unsigned int)seqnum+i, + (unsigned int)seqnum)); + break; } } -#endif /* JRATEST */ - } else { - DEBUG(10, ("srv_check_incoming_message: seq %u: (current is %u) got good SMB signature of\n", (unsigned int)reply_seq_number, (unsigned int)data->send_seq_num)); - dump_data(10, server_sent_mac, 8); + DEBUG(10, ("smb_signing_check_pdu: seq %u: " + "got good SMB signature of\n", + (unsigned int)seqnum)); + dump_data(10, reply_sent_mac, 8); } - return (signing_good(inbuf, si, good, saved_seq, must_be_ok)); + return smb_signing_good(si, good, seqnum); } -/*********************************************************** - SMB signing - server API's. -************************************************************/ - -static struct smb_sign_info srv_sign_info = { - null_sign_outgoing_message, - null_check_incoming_message, - null_free_signing_context, - NULL, - False, - False, - False, - False -}; - -/*********************************************************** - Turn signing off or on for oplock break code. -************************************************************/ - -bool srv_oplock_set_signing(bool onoff) +bool smb_signing_set_bsrspyl(struct smb_signing_state *si) { - bool ret = srv_sign_info.doing_signing; - srv_sign_info.doing_signing = onoff; - return ret; -} - -/*********************************************************** - Called to validate an incoming packet from the client. -************************************************************/ - -bool srv_check_sign_mac(const char *inbuf, bool must_be_ok) -{ - /* Check if it's a non-session message. */ - if(CVAL(inbuf,0)) { - return True; + if (!si->negotiated) { + return false; } - return srv_sign_info.check_incoming_message(inbuf, &srv_sign_info, must_be_ok); -} - -/*********************************************************** - Called to sign an outgoing packet to the client. -************************************************************/ - -void srv_calculate_sign_mac(char *outbuf) -{ - /* Check if it's a non-session message. */ - if(CVAL(outbuf,0)) { - return; + if (si->active) { + return false; } - srv_sign_info.sign_outgoing_message(outbuf, &srv_sign_info); -} + si->bsrspyl = true; -/*********************************************************** - Called by server to defer an outgoing packet. -************************************************************/ + return true; +} -void srv_defer_sign_response(uint16 mid) +bool smb_signing_activate(struct smb_signing_state *si, + const DATA_BLOB user_session_key, + const DATA_BLOB response) { - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) - return; + size_t len; + off_t ofs; - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + if (!user_session_key.length) { + return false; + } - if (!data) - return; + if (!si->negotiated) { + return false; + } - /* - * Ensure we only store this mid reply once... - */ + if (si->active) { + return false; + } - store_sequence_for_reply(&data->outstanding_packet_list, mid, - data->send_seq_num-1); -} + if (si->mac_key.length > 0) { + return false; + } -/*********************************************************** - Called to remove sequence records when a deferred packet is - cancelled by mid. This should never find one.... -************************************************************/ + smb_signing_reset_info(si); -void srv_cancel_sign_response(uint16 mid, bool cancel) -{ - struct smb_basic_signing_context *data; - uint32 dummy_seq; + len = response.length + user_session_key.length; + si->mac_key = data_blob_talloc(si, NULL, len); - if (!srv_sign_info.doing_signing) - return; + ofs = 0; + memcpy(&si->mac_key.data[ofs], user_session_key.data, user_session_key.length); - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; + DEBUG(10, ("smb_signing_activate: user_session_key\n")); + dump_data(10, user_session_key.data, user_session_key.length); - if (!data) - return; + if (response.length) { + ofs = user_session_key.length; + memcpy(&si->mac_key.data[ofs], response.data, response.length); + DEBUG(10, ("smb_signing_activate: response_data\n")); + dump_data(10, response.data, response.length); + } else { + DEBUG(10, ("smb_signing_activate: NULL response_data\n")); + } - DEBUG(10,("srv_cancel_sign_response: for mid %u\n", (unsigned int)mid )); + dump_data_pw("smb_signing_activate: mac key is:\n", + si->mac_key.data, si->mac_key.length); - while (get_sequence_for_reply(&data->outstanding_packet_list, mid, &dummy_seq)) - ; + /* Initialise the sequence number */ + si->seqnum = 2; - /* cancel doesn't send a reply so doesn't burn a sequence number. */ - if (cancel) { - data->send_seq_num -= 1; - } + return true; } -/*********************************************************** - Called by server negprot when signing has been negotiated. -************************************************************/ - -void srv_set_signing_negotiated(void) +bool smb_signing_is_active(struct smb_signing_state *si) { - srv_sign_info.allow_smb_signing = True; - srv_sign_info.negotiated_smb_signing = True; - if (lp_server_signing() == Required) - srv_sign_info.mandatory_signing = True; - - srv_sign_info.sign_outgoing_message = temp_sign_outgoing_message; - srv_sign_info.check_incoming_message = temp_check_incoming_message; - srv_sign_info.free_signing_context = temp_free_signing_context; + return si->active; } -/*********************************************************** - Returns whether signing is active. We can't use sendfile or raw - reads/writes if it is. -************************************************************/ - -bool srv_is_signing_active(void) +bool smb_signing_is_allowed(struct smb_signing_state *si) { - return srv_sign_info.doing_signing; + return si->allowed; } - -/*********************************************************** - Returns whether signing is negotiated. We can't use it unless it was - in the negprot. -************************************************************/ - -bool srv_is_signing_negotiated(void) +bool smb_signing_is_mandatory(struct smb_signing_state *si) { - return srv_sign_info.negotiated_smb_signing; + return si->mandatory; } -/*********************************************************** - Returns whether signing is actually happening -************************************************************/ - -bool srv_signing_started(void) +bool smb_signing_set_negotiated(struct smb_signing_state *si) { - struct smb_basic_signing_context *data; - - if (!srv_sign_info.doing_signing) { - return False; + if (!si->allowed) { + return false; } - data = (struct smb_basic_signing_context *)srv_sign_info.signing_context; - if (!data) - return False; + si->negotiated = true; - if (data->send_seq_num == 0) { - return False; - } - - return True; + return true; } -/*********************************************************** - Turn on signing from this packet onwards. -************************************************************/ - -void srv_set_signing(const DATA_BLOB user_session_key, const DATA_BLOB response) +bool smb_signing_is_negotiated(struct smb_signing_state *si) { - struct smb_basic_signing_context *data; - - if (!user_session_key.length) - return; - - if (!srv_sign_info.negotiated_smb_signing && !srv_sign_info.mandatory_signing) { - DEBUG(5,("srv_set_signing: signing negotiated = %u, mandatory_signing = %u. Not allowing smb signing.\n", - (unsigned int)srv_sign_info.negotiated_smb_signing, - (unsigned int)srv_sign_info.mandatory_signing )); - return; - } - - /* Once we've turned on, ignore any more sessionsetups. */ - if (srv_sign_info.doing_signing) { - return; - } - - if (srv_sign_info.free_signing_context) - srv_sign_info.free_signing_context(&srv_sign_info); - - srv_sign_info.doing_signing = True; - - data = SMB_XMALLOC_P(struct smb_basic_signing_context); - memset(data, '\0', sizeof(*data)); - - srv_sign_info.signing_context = data; - - data->mac_key = data_blob(NULL, response.length + user_session_key.length); - - memcpy(&data->mac_key.data[0], user_session_key.data, user_session_key.length); - if (response.length) - memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length); - - dump_data_pw("MAC ssession key is:\n", data->mac_key.data, data->mac_key.length); - - DEBUG(3,("srv_set_signing: turning on SMB signing: signing negotiated = %s, mandatory_signing = %s.\n", - BOOLSTR(srv_sign_info.negotiated_smb_signing), - BOOLSTR(srv_sign_info.mandatory_signing) )); - - /* Initialise the sequence number */ - data->send_seq_num = 0; - - /* Initialise the list of outstanding packets */ - data->outstanding_packet_list = NULL; - - srv_sign_info.sign_outgoing_message = srv_sign_outgoing_message; - srv_sign_info.check_incoming_message = srv_check_incoming_message; - srv_sign_info.free_signing_context = simple_free_signing_context; + return si->negotiated; } diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c index df4d2119e2..d123e24aa8 100644 --- a/source3/libsmb/unexpected.c +++ b/source3/libsmb/unexpected.c @@ -162,6 +162,8 @@ static int traverse_match(TDB_CONTEXT *ttdb, TDB_DATA kbuf, TDB_DATA dbuf, state->match_type, ip, port); + if (!p) + return 0; if ((state->match_type == NMB_PACKET && p->packet.nmb.header.name_trn_id == state->match_id) || diff --git a/source3/locking/locking.c b/source3/locking/locking.c index bafb89522a..70841225a7 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -887,7 +887,8 @@ struct share_mode_lock *fetch_share_mode_unlocked(TALLOC_CTX *mem_ctx, } if (!fill_share_mode_lock(lck, id, servicepath, fname, data, NULL)) { - DEBUG(3, ("fill_share_mode_lock failed\n")); + DEBUG(10, ("fetch_share_mode_unlocked: no share_mode record " + "around (file not open)\n")); TALLOC_FREE(lck); return NULL; } diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 7756f8f3ab..462e59313a 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -315,7 +315,7 @@ static NTSTATUS smb_get_nt_acl_nfs4_common(const SMB_STRUCT_STAT *sbuf, } DEBUG(10, ("smb_get_nt_acl_nfs4_common successfully exited with sd_size %d\n", - ndr_size_security_descriptor(*ppdesc, 0))); + ndr_size_security_descriptor(*ppdesc, NULL, 0))); return NT_STATUS_OK; } diff --git a/source3/modules/onefs_acl.c b/source3/modules/onefs_acl.c index 6f23d608d4..8ee31abc88 100644 --- a/source3/modules/onefs_acl.c +++ b/source3/modules/onefs_acl.c @@ -825,7 +825,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, /* Setup owner */ if (security_info_sent & OWNER_SECURITY_INFORMATION) { if (!onefs_og_to_identity(psd->owner_sid, &owner, false, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; SMB_ASSERT(owner.id.uid >= 0); @@ -835,7 +835,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, /* Setup group */ if (security_info_sent & GROUP_SECURITY_INFORMATION) { if (!onefs_og_to_identity(psd->group_sid, &group, true, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; SMB_ASSERT(group.id.gid >= 0); @@ -846,7 +846,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, if ((security_info_sent & DACL_SECURITY_INFORMATION) && (psd->dacl)) { if (!onefs_samba_acl_to_acl(psd->dacl, &daclp, &ignore_aces, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; if (ignore_aces == true) security_info_sent &= ~DACL_SECURITY_INFORMATION; @@ -863,7 +863,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, if (psd->sacl) { if (!onefs_samba_acl_to_acl(psd->sacl, &saclp, &ignore_aces, snum)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; if (ignore_aces == true) { security_info_sent &= @@ -877,7 +877,7 @@ NTSTATUS onefs_samba_sd_to_sd(uint32 security_info_sent, SEC_DESC *psd, DEBUG(5,("Setting up SD\n")); if (aclu_initialize_sd(sd, psd->type, ownerp, groupp, (daclp ? &daclp : NULL), (saclp ? &saclp : NULL), false)) - return NT_STATUS_UNSUCCESSFUL; + return NT_STATUS_ACCESS_DENIED; return NT_STATUS_OK; } diff --git a/source3/modules/onefs_open.c b/source3/modules/onefs_open.c index c5030f4ab8..c23c176b79 100644 --- a/source3/modules/onefs_open.c +++ b/source3/modules/onefs_open.c @@ -208,14 +208,14 @@ static NTSTATUS onefs_open_file(files_struct *fsp, if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) != NO_OPLOCK) { DEBUG(0,("Oplock(%d) being requested on a stream! " - "Ignoring oplock request: base=%s, stream=%s", + "Ignoring oplock request: base=%s, stream=%s\n", oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK, base, stream)); /* Recover by requesting NO_OPLOCK instead. */ oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK; } - DEBUG(10,("Opening a stream: base=%s(%d), stream=%s", + DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n", base, fsp->base_fsp->fh->fd, stream)); base_fd = fsp->base_fsp->fh->fd; @@ -386,15 +386,6 @@ static void defer_open(struct share_mode_lock *lck, exit_server("push_deferred_smb_message failed"); } add_deferred_open(lck, req->mid, request_time, state->id); - - /* - * Push the MID of this packet on the signing queue. - * We only do this once, the first time we push the packet - * onto the deferred open queue, as this has a side effect - * of incrementing the response sequence number. - */ - - srv_defer_sign_response(req->mid); } static void schedule_defer_open(struct share_mode_lock *lck, diff --git a/source3/modules/perfcount_onefs.c b/source3/modules/perfcount_onefs.c index 9b35af699a..066a7f1fe4 100644 --- a/source3/modules/perfcount_onefs.c +++ b/source3/modules/perfcount_onefs.c @@ -20,8 +20,11 @@ #include "includes.h" #include <sys/isi_stats_protocol.h> +#include <sys/isi_stats_client.h> #include <sys/isi_stats_cifs.h> +extern struct current_user current_user; + struct onefs_op_counter { struct isp_op_delta iod; struct onefs_op_counter *next; @@ -282,42 +285,64 @@ static void onefs_smb_statistics_defer_op(struct smb_perfcount_data *pcd, pcd->context = NULL; } -static void onefs_smb_statistics_set_client(struct smb_perfcount_data *pcd, - uid_t uid, const char *user, - const char *domain) -{ - // not implemented... - return; -} - static void onefs_smb_statistics_end(struct smb_perfcount_data *pcd) { struct onefs_stats_context *ctxt = pcd->context; struct onefs_op_counter *tmp; + uint64_t uid; + + static in_addr_t rem_addr = 0; + static in_addr_t loc_addr = 0; /* not enabled */ if (pcd->context == NULL) return; + uid = current_user.ut.uid ? current_user.ut.uid : ISC_UNKNOWN_CLIENT_ID; + + /* get address info once, doesn't change for process */ + if (rem_addr == 0) { + struct sockaddr_storage sa; + socklen_t sa_len; + int fd = smbd_server_fd(); + + sa_len = sizeof sa; + if (getpeername(fd, (struct sockaddr *)&sa, &sa_len) == 0 && + sa.ss_family == AF_INET) + rem_addr = ((struct sockaddr_in *)&sa)->sin_addr.s_addr; + else + rem_addr = ISC_MASKED_ADDR; + + sa_len = sizeof sa; + if (getsockname(fd, (struct sockaddr *)&sa, &sa_len) == 0 && + sa.ss_family == AF_INET) + loc_addr = ((struct sockaddr_in *)&sa)->sin_addr.s_addr; + else + loc_addr = ISC_MASKED_ADDR; + } + /* * bug here - we aren't getting the outlens right, * when dealing w/ chained requests. */ for (tmp = ctxt->ops_chain; tmp; tmp = tmp->next) { tmp->iod.out_bytes = ctxt->iod.out_bytes; + isc_cookie_init(&tmp->iod.cookie, rem_addr, loc_addr, uid); ISP_OP_END(&tmp->iod); #ifdef ONEFS_PERF_DEBUG - DEBUG(0,("******** Finalized CHAIN op %s in:%llu, out:%llu\n", - onefs_stat_debug(&tmp->iod), + DEBUG(0,("******** Finalized CHAIN op %s uid %llu in:%llu" + ", out:%llu\n", + onefs_stat_debug(&tmp->iod), uid, tmp->iod.in_bytes, tmp->iod.out_bytes)); #endif SAFE_FREE(tmp->prev); } - ISP_OP_END(&ctxt->iod); + isc_cookie_init(&ctxt->iod.cookie, rem_addr, loc_addr, uid); + ISP_OP_END(&ctxt->iod); #ifdef ONEFS_PERF_DEBUG - DEBUG(0,("******** Finalized op %s in:%llu, out:%llu\n", - onefs_stat_debug(&ctxt->iod), + DEBUG(0,("******** Finalized op %s uid %llu in:%llu, out:%llu\n", + onefs_stat_debug(&ctxt->iod), uid, ctxt->iod.in_bytes, ctxt->iod.out_bytes)); #endif @@ -338,7 +363,6 @@ static struct smb_perfcount_handlers onefs_pc_handlers = { onefs_smb_statistics_set_ioctl, onefs_smb_statistics_set_msglen_in, onefs_smb_statistics_set_msglen_out, - onefs_smb_statistics_set_client, onefs_smb_statistics_copy_context, onefs_smb_statistics_defer_op, onefs_smb_statistics_end diff --git a/source3/modules/perfcount_test.c b/source3/modules/perfcount_test.c index 418d83ace5..b72ac9f7b5 100644 --- a/source3/modules/perfcount_test.c +++ b/source3/modules/perfcount_test.c @@ -351,14 +351,6 @@ static void perfcount_test_defer_op(struct smb_perfcount_data *pcd, return; } -static void perfcount_test_set_client(struct smb_perfcount_data *pcd, - uid_t uid, const char *user, - const char *domain) -{ - /* WIP */ - return; -} - static void perfcount_test_end(struct smb_perfcount_data *pcd) { struct perfcount_test_context *ctxt = @@ -382,7 +374,6 @@ static struct smb_perfcount_handlers perfcount_test_handlers = { perfcount_test_set_ioctl, perfcount_test_set_msglen_in, perfcount_test_set_msglen_out, - perfcount_test_set_client, perfcount_test_copy_context, perfcount_test_defer_op, perfcount_test_end diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c new file mode 100644 index 0000000000..53d1820c11 --- /dev/null +++ b/source3/modules/vfs_dirsort.c @@ -0,0 +1,194 @@ +/* + * VFS module to provide a sorted directory list. + * + * Copyright (C) Andy Kelk (andy@mopoke.co.uk), 2009 + * + * + * 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" + +static int compare_dirent (const void *a, const void *b) { + const SMB_STRUCT_DIRENT *da = (const SMB_STRUCT_DIRENT *) a; + const SMB_STRUCT_DIRENT *db = (const SMB_STRUCT_DIRENT *) b; + return StrCaseCmp(da->d_name, db->d_name); +} + +struct dirsort_privates { + long pos; + SMB_STRUCT_DIRENT *directory_list; + long number_of_entries; + time_t mtime; + SMB_STRUCT_DIR *source_directory; + int fd; +}; + +static void free_dirsort_privates(void **datap) { + struct dirsort_privates *data = (struct dirsort_privates *) *datap; + SAFE_FREE(data->directory_list); + SAFE_FREE(data); + *datap = NULL; + + return; +} + +static void open_and_sort_dir (vfs_handle_struct *handle) +{ + SMB_STRUCT_DIRENT *dp; + struct stat dir_stat; + long current_pos; + struct dirsort_privates *data = NULL; + + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return); + + data->number_of_entries = 0; + + if (fstat(data->fd, &dir_stat) == 0) { + data->mtime = dir_stat.st_mtime; + } + + while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL) + != NULL) { + data->number_of_entries++; + } + + /* Open the underlying directory and count the number of entries + Skip back to the beginning as we'll read it again */ + SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory); + + /* Set up an array and read the directory entries into it */ + SAFE_FREE(data->directory_list); /* destroy previous cache if needed */ + data->directory_list = (SMB_STRUCT_DIRENT *)SMB_MALLOC( + data->number_of_entries * sizeof(SMB_STRUCT_DIRENT)); + current_pos = data->pos; + data->pos = 0; + while ((dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, + NULL)) != NULL) { + data->directory_list[data->pos++] = *dp; + } + + /* Sort the directory entries by name */ + data->pos = current_pos; + qsort(data->directory_list, data->number_of_entries, + sizeof(SMB_STRUCT_DIRENT), compare_dirent); +} + +static SMB_STRUCT_DIR *dirsort_opendir(vfs_handle_struct *handle, + const char *fname, const char *mask, + uint32 attr) +{ + struct dirsort_privates *data = NULL; + + /* set up our private data about this directory */ + data = (struct dirsort_privates *)SMB_MALLOC( + sizeof(struct dirsort_privates)); + + data->directory_list = NULL; + data->pos = 0; + + /* Open the underlying directory and count the number of entries */ + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, + attr); + + data->fd = dirfd(data->source_directory); + + SMB_VFS_HANDLE_SET_DATA(handle, data, free_dirsort_privates, + struct dirsort_privates, return NULL); + + open_and_sort_dir(handle); + + return data->source_directory; +} + +static SMB_STRUCT_DIRENT *dirsort_readdir(vfs_handle_struct *handle, + SMB_STRUCT_DIR *dirp) +{ + struct dirsort_privates *data = NULL; + time_t current_mtime; + struct stat dir_stat; + + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, + return NULL); + + if (fstat(data->fd, &dir_stat) == -1) { + return NULL; + } + + current_mtime = dir_stat.st_mtime; + + /* throw away cache and re-read the directory if we've changed */ + if (current_mtime > data->mtime) { + open_and_sort_dir(handle); + } + + if (data->pos >= data->number_of_entries) { + return NULL; + } + + return &data->directory_list[data->pos++]; +} + +static void dirsort_seekdir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp, + long offset) +{ + struct dirsort_privates *data = NULL; + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return); + + data->pos = offset; +} + +static long dirsort_telldir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + struct dirsort_privates *data = NULL; + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, + return -1); + + return data->pos; +} + +static void dirsort_rewinddir(vfs_handle_struct *handle, SMB_STRUCT_DIR *dirp) +{ + struct dirsort_privates *data = NULL; + SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return); + + data->pos = 0; +} + +/* VFS operations structure */ + +static vfs_op_tuple dirsort_op_tuples[] = { + + /* Directory operations */ + + {SMB_VFS_OP(dirsort_opendir), SMB_VFS_OP_OPENDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_readdir), SMB_VFS_OP_READDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_seekdir), SMB_VFS_OP_SEEKDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_telldir), SMB_VFS_OP_TELLDIR, + SMB_VFS_LAYER_TRANSPARENT}, + {SMB_VFS_OP(dirsort_rewinddir), SMB_VFS_OP_REWINDDIR, + SMB_VFS_LAYER_TRANSPARENT}, + + {NULL, SMB_VFS_OP_NOOP, + SMB_VFS_LAYER_NOOP} +}; + +NTSTATUS vfs_dirsort_init(void) +{ + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "dirsort", + dirsort_op_tuples); +} diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c index 023d2b9ec0..e5a70b1a49 100644 --- a/source3/modules/vfs_streams_depot.c +++ b/source3/modules/vfs_streams_depot.c @@ -78,7 +78,7 @@ static bool file_is_valid(vfs_handle_struct *handle, const char *path, DEBUG(10, ("file_is_valid (%s) called\n", path)); - if (SMB_VFS_NEXT_GETXATTR(handle, path, SAMBA_XATTR_MARKER, + if (SMB_VFS_GETXATTR(handle->conn, path, SAMBA_XATTR_MARKER, &buf, sizeof(buf)) != sizeof(buf)) { DEBUG(10, ("GETXATTR failed: %s\n", strerror(errno))); return false; @@ -104,7 +104,7 @@ static bool mark_file_valid(vfs_handle_struct *handle, const char *path, DEBUG(10, ("marking file %s as valid\n", path)); - ret = SMB_VFS_NEXT_SETXATTR(handle, path, SAMBA_XATTR_MARKER, + ret = SMB_VFS_SETXATTR(handle->conn, path, SAMBA_XATTR_MARKER, &buf, sizeof(buf), 0); if (ret == -1) { diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index 3279466602..daf4c295a6 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -988,6 +988,12 @@ static bool open_sockets(bool isdaemon, int port) exit(1); } + if (!initialize_nmbd_proxy_logon()) { + DEBUG(0,("ERROR: Failed setup nmbd_proxy_logon.\n")); + kill_async_dns_child(); + exit(1); + } + TALLOC_FREE(frame); process(); diff --git a/source3/nmbd/nmbd_elections.c b/source3/nmbd/nmbd_elections.c index b50d215b91..1ed64f4059 100644 --- a/source3/nmbd/nmbd_elections.c +++ b/source3/nmbd/nmbd_elections.c @@ -130,9 +130,6 @@ void check_master_browser_exists(time_t t) struct subnet_record *subrec; const char *workgroup_name = lp_workgroup(); - if (!lastrun) - lastrun = t; - if (t < (lastrun + (CHECK_TIME_MST_BROWSE * 60))) return; diff --git a/source3/nmbd/nmbd_processlogon.c b/source3/nmbd/nmbd_processlogon.c index 59a2ca405e..8173337da0 100644 --- a/source3/nmbd/nmbd_processlogon.c +++ b/source3/nmbd/nmbd_processlogon.c @@ -24,6 +24,9 @@ */ #include "includes.h" +#include "../libcli/netlogon.h" +#include "../libcli/cldap/cldap.h" +#include "../lib/tsocket/tsocket.h" struct sam_database_info { uint32 index; @@ -65,6 +68,235 @@ static void delayed_init_logon_handler(struct event_context *event_ctx, TALLOC_FREE(te); } +struct nmbd_proxy_logon_context { + struct cldap_socket *cldap_sock; +}; + +static struct nmbd_proxy_logon_context *global_nmbd_proxy_logon; + +bool initialize_nmbd_proxy_logon(void) +{ + const char *cldap_server = lp_parm_const_string(-1, "nmbd_proxy_logon", + "cldap_server", NULL); + struct nmbd_proxy_logon_context *ctx; + NTSTATUS status; + struct in_addr addr; + char addrstr[INET_ADDRSTRLEN]; + const char *server_str; + int ret; + struct tsocket_address *server_addr; + + if (!cldap_server) { + return true; + } + + addr = interpret_addr2(cldap_server); + server_str = inet_ntop(AF_INET, &addr, + addrstr, sizeof(addrstr)); + if (!server_str || strcmp("0.0.0.0", server_str) == 0) { + DEBUG(0,("Failed to resolve[%s] for nmbd_proxy_logon\n", + cldap_server)); + return false; + } + + ctx = talloc_zero(nmbd_event_context(), + struct nmbd_proxy_logon_context); + if (!ctx) { + return false; + } + + ret = tsocket_address_inet_from_strings(ctx, "ipv4", + server_str, LDAP_PORT, + &server_addr); + if (ret != 0) { + TALLOC_FREE(ctx); + status = map_nt_error_from_unix(errno); + DEBUG(0,("Failed to create cldap tsocket_address for %s - %s\n", + server_str, nt_errstr(status))); + return false; + } + + /* we create a connected udp socket */ + status = cldap_socket_init(ctx, nmbd_event_context(), NULL, + server_addr, &ctx->cldap_sock); + TALLOC_FREE(server_addr); + if (!NT_STATUS_IS_OK(status)) { + TALLOC_FREE(ctx); + DEBUG(0,("failed to create cldap socket for %s: %s\n", + server_str, nt_errstr(status))); + return false; + } + + global_nmbd_proxy_logon = ctx; + return true; +} + +struct nmbd_proxy_logon_state { + struct in_addr local_ip; + struct packet_struct *p; + const char *remote_name; + uint8_t remote_name_type; + const char *remote_mailslot; + struct nbt_netlogon_packet req; + struct nbt_netlogon_response resp; + struct cldap_netlogon io; +}; + +static int nmbd_proxy_logon_state_destructor(struct nmbd_proxy_logon_state *s) +{ + s->p->locked = false; + free_packet(s->p); + return 0; +} + +static void nmbd_proxy_logon_done(struct tevent_req *subreq); + +static void nmbd_proxy_logon(struct nmbd_proxy_logon_context *ctx, + struct in_addr local_ip, + struct packet_struct *p, + uint8_t *buf, + uint32_t len) +{ + struct nmbd_proxy_logon_state *state; + enum ndr_err_code ndr_err; + DATA_BLOB blob = data_blob_const(buf, len); + const char *computer_name = NULL; + const char *mailslot_name = NULL; + const char *user_name = NULL; + const char *domain_sid = NULL; + uint32_t acct_control = 0; + uint32_t nt_version = 0; + struct tevent_req *subreq; + fstring source_name; + struct dgram_packet *dgram = &p->packet.dgram; + + state = TALLOC_ZERO_P(ctx, struct nmbd_proxy_logon_state); + if (!state) { + DEBUG(0,("failed to allocate nmbd_proxy_logon_state\n")); + return; + } + + pull_ascii_nstring(source_name, sizeof(source_name), dgram->source_name.name); + state->remote_name = talloc_strdup(state, source_name); + state->remote_name_type = dgram->source_name.name_type, + state->local_ip = local_ip; + state->p = p; + + ndr_err = ndr_pull_struct_blob( + &blob, state, NULL, &state->req, + (ndr_pull_flags_fn_t)ndr_pull_nbt_netlogon_packet); + if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { + NTSTATUS status = ndr_map_error2ntstatus(ndr_err); + DEBUG(0,("failed parse nbt_letlogon_packet: %s\n", + nt_errstr(status))); + TALLOC_FREE(state); + return; + } + + if (DEBUGLEVEL >= 10) { + DEBUG(10, ("nmbd_proxy_logon:\n")); + NDR_PRINT_DEBUG(nbt_netlogon_packet, &state->req); + } + + switch (state->req.command) { + case LOGON_SAM_LOGON_REQUEST: + computer_name = state->req.req.logon.computer_name; + user_name = state->req.req.logon.user_name; + mailslot_name = state->req.req.logon.mailslot_name; + acct_control = state->req.req.logon.acct_control; + if (state->req.req.logon.sid_size > 0) { + domain_sid = dom_sid_string(state, + &state->req.req.logon.sid); + if (!domain_sid) { + DEBUG(0,("failed to get a string for sid\n")); + TALLOC_FREE(state); + return; + } + } + nt_version = state->req.req.logon.nt_version; + break; + + default: + /* this can't happen as the caller already checks the command */ + break; + } + + state->remote_mailslot = mailslot_name; + + if (user_name && strlen(user_name) == 0) { + user_name = NULL; + } + + if (computer_name && strlen(computer_name) == 0) { + computer_name = NULL; + } + + /* + * as the socket is connected, + * we don't need to specify the destination + */ + state->io.in.dest_address = NULL; + state->io.in.dest_port = 0; + state->io.in.realm = NULL; + state->io.in.host = computer_name; + state->io.in.user = user_name; + state->io.in.domain_guid = NULL; + state->io.in.domain_sid = domain_sid; + state->io.in.acct_control = acct_control; + state->io.in.version = nt_version; + state->io.in.map_response = false; + + subreq = cldap_netlogon_send(state, + ctx->cldap_sock, + &state->io); + if (!subreq) { + DEBUG(0,("failed to send cldap netlogon call\n")); + TALLOC_FREE(state); + return; + } + tevent_req_set_callback(subreq, nmbd_proxy_logon_done, state); + + /* we reply async */ + state->p->locked = true; + talloc_set_destructor(state, nmbd_proxy_logon_state_destructor); +} + +static void nmbd_proxy_logon_done(struct tevent_req *subreq) +{ + struct nmbd_proxy_logon_state *state = + tevent_req_callback_data(subreq, + struct nmbd_proxy_logon_state); + NTSTATUS status; + DATA_BLOB response; + + status = cldap_netlogon_recv(subreq, NULL, state, &state->io); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("failed to recv cldap netlogon call: %s\n", + nt_errstr(status))); + TALLOC_FREE(state); + return; + } + + status = push_netlogon_samlogon_response(&response, state, NULL, + &state->io.out.netlogon); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("failed to push netlogon_samlogon_response: %s\n", + nt_errstr(status))); + TALLOC_FREE(state); + return; + } + + send_mailslot(true, state->remote_mailslot, + (char *)response.data, response.length, + global_myname(), 0x0, + state->remote_name, + state->remote_name_type, + state->p->ip, + state->local_ip, + state->p->port); + TALLOC_FREE(state); +} + /**************************************************************************** Process a domain logon packet **************************************************************************/ @@ -318,6 +550,12 @@ reporting %s domain %s 0x%x ntversion=%x lm_nt token=%x lm_20 token=%x\n", char *q = buf + 2; fstring asccomp; + if (global_nmbd_proxy_logon) { + nmbd_proxy_logon(global_nmbd_proxy_logon, + ip, p, (uint8_t *)buf, len); + return; + } + q += 2; if (PTR_DIFF(q, buf) >= len) { diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index f49a1bc4c9..66fb8bf1bc 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -9542,10 +9542,6 @@ const char *lp_printcapname(void) return PRINTCAP_NAME; } -/******************************************************************* - Ensure we don't use sendfile if server smb signing is active. -********************************************************************/ - static uint32 spoolss_state; bool lp_disable_spoolss( void ) @@ -9572,15 +9568,20 @@ uint32 lp_get_spoolss_state( void ) Ensure we don't use sendfile if server smb signing is active. ********************************************************************/ -bool lp_use_sendfile(int snum) +bool lp_use_sendfile(int snum, struct smb_signing_state *signing_state) { + bool sign_active = false; + /* Using sendfile blows the brains out of any DOS or Win9x TCP stack... JRA. */ if (Protocol < PROTOCOL_NT1) { - return False; + return false; + } + if (signing_state) { + sign_active = smb_signing_is_active(signing_state); } return (_lp_use_sendfile(snum) && (get_remote_arch() != RA_WIN95) && - !srv_is_signing_active()); + !sign_active); } /******************************************************************* diff --git a/source3/passdb/lookup_sid.c b/source3/passdb/lookup_sid.c index 9c20042a62..a5c2d50366 100644 --- a/source3/passdb/lookup_sid.c +++ b/source3/passdb/lookup_sid.c @@ -804,7 +804,7 @@ NTSTATUS lookup_sids(TALLOC_CTX *mem_ctx, int num_sids, } else { /* This is a normal SID with rid component */ if (!sid_split_rid(&sid, &rid)) { - result = NT_STATUS_INVALID_PARAMETER; + result = NT_STATUS_INVALID_SID; goto fail; } } diff --git a/source3/passdb/pdb_tdb.c b/source3/passdb/pdb_tdb.c index 73fcfee4b3..1060733df4 100644 --- a/source3/passdb/pdb_tdb.c +++ b/source3/passdb/pdb_tdb.c @@ -4,7 +4,7 @@ * Copyright (C) Andrew Tridgell 1992-1998 * Copyright (C) Simo Sorce 2000-2003 * Copyright (C) Gerald Carter 2000-2006 - * Copyright (C) Jeremy Allison 2001 + * Copyright (C) Jeremy Allison 2001-2009 * Copyright (C) Andrew Bartlett 2002 * Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2005 * @@ -38,7 +38,9 @@ static int tdbsam_debug_level = DBGC_ALL; #endif #define TDBSAM_VERSION 4 /* Most recent TDBSAM version */ +#define TDBSAM_MINOR_VERSION 0 /* Most recent TDBSAM minor version */ #define TDBSAM_VERSION_STRING "INFO/version" +#define TDBSAM_MINOR_VERSION_STRING "INFO/minor_version" #define PASSDB_FILE_NAME "passdb.tdb" #define USERPREFIX "USER_" #define USERPREFIX_LEN 5 @@ -322,7 +324,8 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr struct db_context *db = NULL; int ret; - if (!tdbsam_convert_backup(name, pp_db)) { + /* We only need the update backup for local db's. */ + if (db_is_local(name) && !tdbsam_convert_backup(name, pp_db)) { DEBUG(0, ("tdbsam_convert: Could not backup %s\n", name)); return false; } @@ -358,6 +361,12 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr goto cancel; } + if (dbwrap_store_int32(db, TDBSAM_MINOR_VERSION_STRING, + TDBSAM_MINOR_VERSION) != 0) { + DEBUG(0, ("tdbsam_convert: Could not store tdbsam minor version\n")); + goto cancel; + } + if (db->transaction_commit(db) != 0) { DEBUG(0, ("tdbsam_convert: Could not commit transaction\n")); return false; @@ -381,6 +390,7 @@ static bool tdbsam_convert(struct db_context **pp_db, const char *name, int32 fr static bool tdbsam_open( const char *name ) { int32 version; + int32 minor_version; /* check if we are already open */ @@ -403,6 +413,12 @@ static bool tdbsam_open( const char *name ) version = 0; /* Version not found, assume version 0 */ } + /* Get the minor version */ + minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING); + if (minor_version == -1) { + minor_version = 0; /* Minor version not found, assume 0 */ + } + /* Compare the version */ if (version > TDBSAM_VERSION) { /* Version more recent than the latest known */ @@ -411,7 +427,9 @@ static bool tdbsam_open( const char *name ) return false; } - if ( version < TDBSAM_VERSION ) { + if ( version < TDBSAM_VERSION || + (version == TDBSAM_VERSION && + minor_version < TDBSAM_MINOR_VERSION) ) { /* * Ok - we think we're going to have to convert. * Due to the backup process we now must do to @@ -436,6 +454,12 @@ static bool tdbsam_open( const char *name ) version = 0; /* Version not found, assume version 0 */ } + /* Re-check the minor version */ + minor_version = dbwrap_fetch_int32(db_sam, TDBSAM_MINOR_VERSION_STRING); + if (minor_version == -1) { + minor_version = 0; /* Minor version not found, assume 0 */ + } + /* Compare the version */ if (version > TDBSAM_VERSION) { /* Version more recent than the latest known */ @@ -445,9 +469,24 @@ static bool tdbsam_open( const char *name ) return false; } - if ( version < TDBSAM_VERSION ) { - DEBUG(1, ("tdbsam_open: Converting version %d database to " - "version %d.\n", version, TDBSAM_VERSION)); + if ( version < TDBSAM_VERSION || + (version == TDBSAM_VERSION && + minor_version < TDBSAM_MINOR_VERSION) ) { + /* + * Note that minor versions we read that are greater + * than the current minor version we have hard coded + * are assumed to be compatible if they have the same + * major version. That allows previous versions of the + * passdb code that don't know about minor versions to + * still use this database. JRA. + */ + + DEBUG(1, ("tdbsam_open: Converting version %d.%d database to " + "version %d.%d.\n", + version, + minor_version, + TDBSAM_VERSION, + TDBSAM_MINOR_VERSION)); if ( !tdbsam_convert(&db_sam, name, version) ) { DEBUG(0, ("tdbsam_open: Error when trying to convert " diff --git a/source3/printing/nt_printing.c b/source3/printing/nt_printing.c index 8e6fe1f364..a99485d381 100644 --- a/source3/printing/nt_printing.c +++ b/source3/printing/nt_printing.c @@ -2275,7 +2275,9 @@ static WERROR get_a_printer_driver_3_default(NT_PRINTER_DRIVER_INFO_LEVEL_3 **in /**************************************************************************** ****************************************************************************/ -static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, fstring drivername, const char *arch, uint32 version) +static WERROR get_a_printer_driver_3(NT_PRINTER_DRIVER_INFO_LEVEL_3 **info_ptr, + const char *drivername, const char *arch, + uint32_t version) { NT_PRINTER_DRIVER_INFO_LEVEL_3 driver; TDB_DATA dbuf; @@ -4448,7 +4450,7 @@ bool set_driver_init(NT_PRINTER_INFO_LEVEL *printer, uint32 level) Delete driver init data stored for a specified driver ****************************************************************************/ -bool del_driver_init(char *drivername) +bool del_driver_init(const char *drivername) { char *key; bool ret; @@ -4837,8 +4839,9 @@ uint32 add_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL driver, uint32 level) /**************************************************************************** ****************************************************************************/ -WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32 level, - fstring drivername, const char *architecture, uint32 version) +WERROR get_a_printer_driver(NT_PRINTER_DRIVER_INFO_LEVEL *driver, uint32_t level, + const char *drivername, const char *architecture, + uint32_t version) { WERROR result; diff --git a/source3/registry/regfio.c b/source3/registry/regfio.c index d002bd72e7..e1c04c4777 100644 --- a/source3/registry/regfio.c +++ b/source3/registry/regfio.c @@ -712,8 +712,30 @@ static bool hbin_prs_sk_rec( const char *desc, REGF_HBIN *hbin, int depth, REGF_ if ( !prs_uint32( "size", ps, depth, &sk->size)) return False; - if ( !sec_io_desc( "sec_desc", &sk->sec_desc, ps, depth )) - return False; + { + NTSTATUS status; + TALLOC_CTX *mem_ctx = prs_get_mem_context(&hbin->ps); + DATA_BLOB blob; + + if (MARSHALLING(&hbin->ps)) { + status = marshall_sec_desc(mem_ctx, + sk->sec_desc, + &blob.data, &blob.length); + if (!NT_STATUS_IS_OK(status)) + return False; + if (!prs_copy_data_in(&hbin->ps, (const char *)blob.data, blob.length)) + return False; + } else { + blob = data_blob_const(prs_data_p(&hbin->ps), + prs_data_size(&hbin->ps)); + status = unmarshall_sec_desc(mem_ctx, + blob.data, blob.length, + &sk->sec_desc); + if (!NT_STATUS_IS_OK(status)) + return False; + prs_set_offset(&hbin->ps, blob.length); + } + } end_off = prs_offset( &hbin->ps ); diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 57f49fb83a..6b83c170f5 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -207,18 +207,18 @@ struct rpc_read_state { size_t num_read; }; -static void rpc_read_done(struct async_req *subreq); +static void rpc_read_done(struct tevent_req *subreq); -static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_transport *transport, - uint8_t *data, size_t size) +static struct tevent_req *rpc_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_cli_transport *transport, + uint8_t *data, size_t size) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_read_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -234,34 +234,33 @@ static struct async_req *rpc_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_read_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, rpc_read_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void rpc_read_done(struct async_req *subreq) +static void rpc_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_read_state *state = tevent_req_data( + req, struct rpc_read_state); NTSTATUS status; ssize_t received; status = state->transport->read_recv(subreq, &received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->num_read += received; if (state->num_read == state->size) { - async_req_done(req); + tevent_req_done(req); return; } @@ -269,16 +268,15 @@ static void rpc_read_done(struct async_req *subreq) state->data + state->num_read, state->size - state->num_read, state->transport->priv); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_read_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_read_done, req); } -static NTSTATUS rpc_read_recv(struct async_req *req) +static NTSTATUS rpc_read_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } struct rpc_write_state { @@ -289,18 +287,18 @@ struct rpc_write_state { size_t num_written; }; -static void rpc_write_done(struct async_req *subreq); +static void rpc_write_done(struct tevent_req *subreq); -static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_transport *transport, - const uint8_t *data, size_t size) +static struct tevent_req *rpc_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_cli_transport *transport, + const uint8_t *data, size_t size) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_write_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -315,34 +313,33 @@ static struct async_req *rpc_write_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = rpc_write_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, rpc_write_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void rpc_write_done(struct async_req *subreq) +static void rpc_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_write_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_write_state *state = tevent_req_data( + req, struct rpc_write_state); NTSTATUS status; ssize_t written; status = state->transport->write_recv(subreq, &written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->num_written += written; if (state->num_written == state->size) { - async_req_done(req); + tevent_req_done(req); return; } @@ -350,16 +347,15 @@ static void rpc_write_done(struct async_req *subreq) state->data + state->num_written, state->size - state->num_written, state->transport->priv); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_write_done, req); } -static NTSTATUS rpc_write_recv(struct async_req *req) +static NTSTATUS rpc_write_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } @@ -399,22 +395,23 @@ struct get_complete_frag_state { prs_struct *pdu; }; -static void get_complete_frag_got_header(struct async_req *subreq); -static void get_complete_frag_got_rest(struct async_req *subreq); +static void get_complete_frag_got_header(struct tevent_req *subreq); +static void get_complete_frag_got_rest(struct tevent_req *subreq); -static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - struct rpc_hdr_info *prhdr, - prs_struct *pdu) +static struct tevent_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct rpc_hdr_info *prhdr, + prs_struct *pdu) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct get_complete_frag_state *state; uint32_t pdu_len; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct get_complete_frag_state)) { + req = tevent_req_create(mem_ctx, &state, + struct get_complete_frag_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -437,9 +434,9 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = get_complete_frag_got_header; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, get_complete_frag_got_header, + req); + return req; } status = parse_rpc_header(cli, prhdr, pdu); @@ -463,43 +460,44 @@ static struct async_req *get_complete_frag_send(TALLOC_CTX *mem_ctx, status = NT_STATUS_NO_MEMORY; goto post_status; } - subreq->async.fn = get_complete_frag_got_rest; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, get_complete_frag_got_rest, + req); + return req; } status = NT_STATUS_OK; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; + if (NT_STATUS_IS_OK(status)) { + tevent_req_done(req); + } else { + tevent_req_nterror(req, status); } - TALLOC_FREE(result); - return NULL; + return tevent_req_post(req, ev); } -static void get_complete_frag_got_header(struct async_req *subreq) +static void get_complete_frag_got_header(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct get_complete_frag_state *state = talloc_get_type_abort( - req->private_data, struct get_complete_frag_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct get_complete_frag_state *state = tevent_req_data( + req, struct get_complete_frag_state); NTSTATUS status; status = rpc_read_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } status = parse_rpc_header(state->cli, state->prhdr, state->pdu); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } if (!rpc_grow_buffer(state->pdu, state->prhdr->frag_len)) { - async_req_nterror(req, NT_STATUS_NO_MEMORY); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -512,31 +510,30 @@ static void get_complete_frag_got_header(struct async_req *subreq) state, state->ev, state->cli->transport, (uint8_t *)(prs_data_p(state->pdu) + RPC_HEADER_LEN), state->prhdr->frag_len - RPC_HEADER_LEN); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = get_complete_frag_got_rest; - subreq->async.priv = req; + tevent_req_set_callback(subreq, get_complete_frag_got_rest, req); } -static void get_complete_frag_got_rest(struct async_req *subreq) +static void get_complete_frag_got_rest(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); NTSTATUS status; status = rpc_read_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS get_complete_frag_recv(struct async_req *req) +static NTSTATUS get_complete_frag_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } /**************************************************************************** @@ -1037,22 +1034,22 @@ struct cli_api_pipe_state { uint32_t rdata_len; }; -static void cli_api_pipe_trans_done(struct async_req *subreq); -static void cli_api_pipe_write_done(struct async_req *subreq); -static void cli_api_pipe_read_done(struct async_req *subreq); +static void cli_api_pipe_trans_done(struct tevent_req *subreq); +static void cli_api_pipe_write_done(struct tevent_req *subreq); +static void cli_api_pipe_read_done(struct tevent_req *subreq); -static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_cli_transport *transport, - uint8_t *data, size_t data_len, - uint32_t max_rdata_len) +static struct tevent_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_cli_transport *transport, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct cli_api_pipe_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct cli_api_pipe_state)) { + req = tevent_req_create(mem_ctx, &state, struct cli_api_pipe_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -1072,12 +1069,10 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, subreq = transport->trans_send(state, ev, data, data_len, max_rdata_len, transport->priv); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = cli_api_pipe_trans_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, cli_api_pipe_trans_done, req); + return req; } /* @@ -1089,56 +1084,54 @@ static struct async_req *cli_api_pipe_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - subreq->async.fn = cli_api_pipe_write_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, cli_api_pipe_write_done, req); + return req; status = NT_STATUS_INVALID_PARAMETER; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void cli_api_pipe_trans_done(struct async_req *subreq) +static void cli_api_pipe_trans_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; status = state->transport->trans_recv(subreq, state, &state->rdata, &state->rdata_len); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static void cli_api_pipe_write_done(struct async_req *subreq) +static void cli_api_pipe_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->rdata = TALLOC_ARRAY(state, uint8_t, RPC_HEADER_LEN); - if (async_req_nomem(state->rdata, req)) { + if (tevent_req_nomem(state->rdata, req)) { return; } @@ -1150,40 +1143,39 @@ static void cli_api_pipe_write_done(struct async_req *subreq) subreq = state->transport->read_send(state, state->ev, state->rdata, RPC_HEADER_LEN, state->transport->priv); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = cli_api_pipe_read_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, cli_api_pipe_read_done, req); } -static void cli_api_pipe_read_done(struct async_req *subreq) +static void cli_api_pipe_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; ssize_t received; status = state->transport->read_recv(subreq, &received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } state->rdata_len = received; - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS cli_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +static NTSTATUS cli_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len) { - struct cli_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct cli_api_pipe_state); + struct cli_api_pipe_state *state = tevent_req_data( + req, struct cli_api_pipe_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } @@ -1237,22 +1229,22 @@ static int rpc_api_pipe_state_destructor(struct rpc_api_pipe_state *state) return 0; } -static void rpc_api_pipe_trans_done(struct async_req *subreq); -static void rpc_api_pipe_got_pdu(struct async_req *subreq); +static void rpc_api_pipe_trans_done(struct tevent_req *subreq); +static void rpc_api_pipe_got_pdu(struct tevent_req *subreq); -static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - prs_struct *data, /* Outgoing PDU */ - uint8_t expected_pkt_type) +static struct tevent_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + prs_struct *data, /* Outgoing PDU */ + uint8_t expected_pkt_type) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_api_pipe_state *state; uint16_t max_recv_frag; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_api_pipe_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_api_pipe_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -1288,27 +1280,25 @@ static struct async_req *rpc_api_pipe_send(TALLOC_CTX *mem_ctx, (uint8_t *)prs_data_p(data), prs_offset(data), max_recv_frag); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = rpc_api_pipe_trans_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, rpc_api_pipe_trans_done, req); + return req; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } - TALLOC_FREE(result); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + fail: + TALLOC_FREE(req); return NULL; } -static void rpc_api_pipe_trans_done(struct async_req *subreq) +static void rpc_api_pipe_trans_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_state *state = tevent_req_data( + req, struct rpc_api_pipe_state); NTSTATUS status; uint8_t *rdata = NULL; uint32_t rdata_len = 0; @@ -1318,14 +1308,14 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq) TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("cli_api_pipe failed: %s\n", nt_errstr(status))); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } if (rdata == NULL) { DEBUG(3,("rpc_api_pipe: %s failed to return data.\n", rpccli_pipe_txt(debug_ctx(), state->cli))); - async_req_done(req); + tevent_req_done(req); return; } @@ -1336,7 +1326,7 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq) */ rdata_copy = (char *)memdup(rdata, rdata_len); TALLOC_FREE(rdata); - if (async_req_nomem(rdata_copy, req)) { + if (tevent_req_nomem(rdata_copy, req)) { return; } prs_give_memory(&state->incoming_frag, rdata_copy, rdata_len, true); @@ -1344,19 +1334,18 @@ static void rpc_api_pipe_trans_done(struct async_req *subreq) /* Ensure we have enough data for a pdu. */ subreq = get_complete_frag_send(state, state->ev, state->cli, &state->rhdr, &state->incoming_frag); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_api_pipe_got_pdu; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req); } -static void rpc_api_pipe_got_pdu(struct async_req *subreq) +static void rpc_api_pipe_got_pdu(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_state *state = tevent_req_data( + req, struct rpc_api_pipe_state); NTSTATUS status; char *rdata = NULL; uint32_t rdata_len = 0; @@ -1366,7 +1355,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq) if (!NT_STATUS_IS_OK(status)) { DEBUG(5, ("get_complete_frag failed: %s\n", nt_errstr(status))); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -1381,7 +1370,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq) nt_errstr(status))); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -1405,13 +1394,13 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq) "%s\n", state->incoming_pdu.bigendian_data?"big":"little", state->incoming_frag.bigendian_data?"big":"little")); - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } /* Now copy the data portion out of the pdu into rbuf. */ if (!prs_force_grow(&state->incoming_pdu, rdata_len)) { - async_req_nterror(req, NT_STATUS_NO_MEMORY); + tevent_req_nterror(req, NT_STATUS_NO_MEMORY); return; } @@ -1422,7 +1411,7 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq) status = cli_pipe_reset_current_pdu(state->cli, &state->rhdr, &state->incoming_frag); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -1430,27 +1419,26 @@ static void rpc_api_pipe_got_pdu(struct async_req *subreq) DEBUG(10,("rpc_api_pipe: %s returned %u bytes.\n", rpccli_pipe_txt(debug_ctx(), state->cli), (unsigned)prs_data_size(&state->incoming_pdu))); - async_req_done(req); + tevent_req_done(req); return; } subreq = get_complete_frag_send(state, state->ev, state->cli, &state->rhdr, &state->incoming_frag); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_api_pipe_got_pdu; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_got_pdu, req); } -static NTSTATUS rpc_api_pipe_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_api_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, prs_struct *reply_pdu) { - struct rpc_api_pipe_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_state); + struct rpc_api_pipe_state *state = tevent_req_data( + req, struct rpc_api_pipe_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } @@ -2043,24 +2031,25 @@ static int rpc_api_pipe_req_state_destructor(struct rpc_api_pipe_req_state *s) return 0; } -static void rpc_api_pipe_req_write_done(struct async_req *subreq); -static void rpc_api_pipe_req_done(struct async_req *subreq); +static void rpc_api_pipe_req_write_done(struct tevent_req *subreq); +static void rpc_api_pipe_req_done(struct tevent_req *subreq); static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, bool *is_last_frag); -struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - uint8_t op_num, - prs_struct *req_data) +struct tevent_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + uint8_t op_num, + prs_struct *req_data) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_api_pipe_req_state *state; NTSTATUS status; bool is_last_frag; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_api_pipe_req_state)) { + req = tevent_req_create(mem_ctx, &state, + struct rpc_api_pipe_req_state); + if (req == NULL) { return NULL; } state->ev = ev; @@ -2081,8 +2070,7 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, if (!prs_init(&state->outgoing_frag, cli->max_xmit_frag, state, MARSHALL)) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } talloc_set_destructor(state, rpc_api_pipe_req_state_destructor); @@ -2097,30 +2085,27 @@ struct async_req *rpc_api_pipe_req_send(TALLOC_CTX *mem_ctx, &state->outgoing_frag, RPC_RESPONSE); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = rpc_api_pipe_req_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); } else { subreq = rpc_write_send( state, ev, cli->transport, (uint8_t *)prs_data_p(&state->outgoing_frag), prs_offset(&state->outgoing_frag)); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = rpc_api_pipe_req_write_done; - subreq->async.priv = result; + tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done, + req); } - return result; + return req; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } - TALLOC_FREE(result); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + fail: + TALLOC_FREE(req); return NULL; } @@ -2209,25 +2194,25 @@ static NTSTATUS prepare_next_frag(struct rpc_api_pipe_req_state *state, return status; } -static void rpc_api_pipe_req_write_done(struct async_req *subreq) +static void rpc_api_pipe_req_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_api_pipe_req_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_req_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_req_state *state = tevent_req_data( + req, struct rpc_api_pipe_req_state); NTSTATUS status; bool is_last_frag; status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } status = prepare_next_frag(state, &is_last_frag); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -2235,50 +2220,49 @@ static void rpc_api_pipe_req_write_done(struct async_req *subreq) subreq = rpc_api_pipe_send(state, state->ev, state->cli, &state->outgoing_frag, RPC_RESPONSE); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_api_pipe_req_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_req_done, req); } else { subreq = rpc_write_send( state, state->ev, state->cli->transport, (uint8_t *)prs_data_p(&state->outgoing_frag), prs_offset(&state->outgoing_frag)); - if (async_req_nomem(subreq, req)) { + if (tevent_req_nomem(subreq, req)) { return; } - subreq->async.fn = rpc_api_pipe_req_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_api_pipe_req_write_done, + req); } } -static void rpc_api_pipe_req_done(struct async_req *subreq) +static void rpc_api_pipe_req_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_api_pipe_req_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_req_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_api_pipe_req_state *state = tevent_req_data( + req, struct rpc_api_pipe_req_state); NTSTATUS status; status = rpc_api_pipe_recv(subreq, state, &state->reply_pdu); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -NTSTATUS rpc_api_pipe_req_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +NTSTATUS rpc_api_pipe_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, prs_struct *reply_pdu) { - struct rpc_api_pipe_req_state *state = talloc_get_type_abort( - req->private_data, struct rpc_api_pipe_req_state); + struct rpc_api_pipe_req_state *state = tevent_req_data( + req, struct rpc_api_pipe_req_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { /* * We always have to initialize to reply pdu, even if there is * none. The rpccli_* caller routines expect this. @@ -2306,7 +2290,7 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; - struct async_req *req; + struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = event_context_init(frame); @@ -2319,9 +2303,7 @@ NTSTATUS rpc_api_pipe_req(TALLOC_CTX *mem_ctx, struct rpc_pipe_client *cli, goto fail; } - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } + tevent_req_poll(req, ev); status = rpc_api_pipe_req_recv(req, mem_ctx, out_data); fail: @@ -2522,29 +2504,29 @@ static int rpc_pipe_bind_state_destructor(struct rpc_pipe_bind_state *state) return 0; } -static void rpc_pipe_bind_step_one_done(struct async_req *subreq); -static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, +static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq); +static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu); -static void rpc_bind_auth3_write_done(struct async_req *subreq); -static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, +static void rpc_bind_auth3_write_done(struct tevent_req *subreq); +static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu); -static void rpc_bind_ntlmssp_api_done(struct async_req *subreq); +static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq); -struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - struct rpc_pipe_client *cli, - struct cli_pipe_auth_data *auth) +struct tevent_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + struct rpc_pipe_client *cli, + struct cli_pipe_auth_data *auth) { - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_pipe_bind_state *state; NTSTATUS status; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_pipe_bind_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_pipe_bind_state); + if (req == NULL) { return NULL; } @@ -2577,27 +2559,25 @@ struct async_req *rpc_pipe_bind_send(TALLOC_CTX *mem_ctx, subreq = rpc_api_pipe_send(state, ev, cli, &state->rpc_out, RPC_BINDACK); if (subreq == NULL) { - status = NT_STATUS_NO_MEMORY; - goto post_status; + goto fail; } - subreq->async.fn = rpc_pipe_bind_step_one_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, rpc_pipe_bind_step_one_done, req); + return req; post_status: - if (async_post_ntstatus(result, ev, status)) { - return result; - } - TALLOC_FREE(result); + tevent_req_nterror(req, status); + return tevent_req_post(req, ev); + fail: + TALLOC_FREE(req); return NULL; } -static void rpc_pipe_bind_step_one_done(struct async_req *subreq) +static void rpc_pipe_bind_step_one_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_pipe_bind_state *state = talloc_get_type_abort( - req->private_data, struct rpc_pipe_bind_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_pipe_bind_state *state = tevent_req_data( + req, struct rpc_pipe_bind_state); prs_struct reply_pdu; struct rpc_hdr_info hdr; struct rpc_hdr_ba_info hdr_ba; @@ -2609,7 +2589,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) DEBUG(3, ("rpc_pipe_bind: %s bind request returned %s\n", rpccli_pipe_txt(debug_ctx(), state->cli), nt_errstr(status))); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -2617,7 +2597,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) if (!smb_io_rpc_hdr("hdr", &hdr, &reply_pdu, 0)) { DEBUG(0, ("rpc_pipe_bind: failed to unmarshall RPC_HDR.\n")); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } @@ -2625,14 +2605,14 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) DEBUG(0, ("rpc_pipe_bind: Failed to unmarshall " "RPC_HDR_BA.\n")); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } if (!check_bind_response(&hdr_ba, &state->cli->transfer_syntax)) { DEBUG(2, ("rpc_pipe_bind: check_bind_response failed.\n")); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } @@ -2649,7 +2629,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) case PIPE_AUTH_TYPE_SCHANNEL: /* Bind complete. */ prs_mem_free(&reply_pdu); - async_req_done(req); + tevent_req_done(req); break; case PIPE_AUTH_TYPE_NTLMSSP: @@ -2658,7 +2638,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) &reply_pdu); prs_mem_free(&reply_pdu); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); } break; @@ -2668,7 +2648,7 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) &reply_pdu); prs_mem_free(&reply_pdu); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); } break; @@ -2679,11 +2659,11 @@ static void rpc_pipe_bind_step_one_done(struct async_req *subreq) DEBUG(0,("cli_finish_bind_auth: unknown auth type %u\n", (unsigned int)state->cli->auth->auth_type)); prs_mem_free(&reply_pdu); - async_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); } } -static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, +static NTSTATUS rpc_finish_auth3_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu) @@ -2691,7 +2671,7 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, DATA_BLOB server_response = data_blob_null; DATA_BLOB client_reply = data_blob_null; struct rpc_hdr_auth_info hdr_auth; - struct async_req *subreq; + struct tevent_req *subreq; NTSTATUS status; if ((phdr->auth_len == 0) @@ -2742,27 +2722,26 @@ static NTSTATUS rpc_finish_auth3_bind_send(struct async_req *req, if (subreq == NULL) { return NT_STATUS_NO_MEMORY; } - subreq->async.fn = rpc_bind_auth3_write_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_bind_auth3_write_done, req); return NT_STATUS_OK; } -static void rpc_bind_auth3_write_done(struct async_req *subreq) +static void rpc_bind_auth3_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); NTSTATUS status; status = rpc_write_recv(subreq); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, +static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct tevent_req *req, struct rpc_pipe_bind_state *state, struct rpc_hdr_info *phdr, prs_struct *reply_pdu) @@ -2772,7 +2751,7 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, DATA_BLOB client_reply = data_blob_null; DATA_BLOB tmp_blob = data_blob_null; RPC_HDR_AUTH hdr_auth; - struct async_req *subreq; + struct tevent_req *subreq; NTSTATUS status; if ((phdr->auth_len == 0) @@ -2850,17 +2829,16 @@ static NTSTATUS rpc_finish_spnego_ntlmssp_bind_send(struct async_req *req, if (subreq == NULL) { return NT_STATUS_NO_MEMORY; } - subreq->async.fn = rpc_bind_ntlmssp_api_done; - subreq->async.priv = req; + tevent_req_set_callback(subreq, rpc_bind_ntlmssp_api_done, req); return NT_STATUS_OK; } -static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) +static void rpc_bind_ntlmssp_api_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_pipe_bind_state *state = talloc_get_type_abort( - req->private_data, struct rpc_pipe_bind_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_pipe_bind_state *state = tevent_req_data( + req, struct rpc_pipe_bind_state); DATA_BLOB server_spnego_response = data_blob_null; DATA_BLOB tmp_blob = data_blob_null; prs_struct reply_pdu; @@ -2871,7 +2849,7 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) status = rpc_api_pipe_recv(subreq, talloc_tos(), &reply_pdu); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } @@ -2879,19 +2857,19 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) if (!smb_io_rpc_hdr("rpc_hdr ", &hdr, &reply_pdu, 0)) { DEBUG(0, ("rpc_finish_spnego_ntlmssp_bind: Failed to " "unmarshall RPC_HDR.\n")); - async_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); + tevent_req_nterror(req, NT_STATUS_BUFFER_TOO_SMALL); return; } if (!prs_set_offset( &reply_pdu, hdr.frag_len - hdr.auth_len - RPC_HDR_AUTH_LEN)) { - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } if (!smb_io_rpc_hdr_auth("hdr_auth", &hdr_auth, &reply_pdu, 0)) { - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2904,7 +2882,7 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) OID_NTLMSSP, &tmp_blob)) { data_blob_free(&server_spnego_response); data_blob_free(&tmp_blob); - async_req_nterror(req, NT_STATUS_INVALID_PARAMETER); + tevent_req_nterror(req, NT_STATUS_INVALID_PARAMETER); return; } @@ -2913,12 +2891,12 @@ static void rpc_bind_ntlmssp_api_done(struct async_req *subreq) DEBUG(5,("rpc_finish_spnego_ntlmssp_bind: alter context request to " "%s.\n", rpccli_pipe_txt(debug_ctx(), state->cli))); - async_req_done(req); + tevent_req_done(req); } -NTSTATUS rpc_pipe_bind_recv(struct async_req *req) +NTSTATUS rpc_pipe_bind_recv(struct tevent_req *req) { - return async_req_simple_recv_ntstatus(req); + return tevent_req_simple_recv_ntstatus(req); } NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, @@ -2926,7 +2904,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, { TALLOC_CTX *frame = talloc_stackframe(); struct event_context *ev; - struct async_req *req; + struct tevent_req *req; NTSTATUS status = NT_STATUS_NO_MEMORY; ev = event_context_init(frame); @@ -2939,9 +2917,7 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli, goto fail; } - while (req->state < ASYNC_REQ_DONE) { - event_loop_once(ev); - } + tevent_req_poll(req, ev); status = rpc_pipe_bind_recv(req); fail: diff --git a/source3/rpc_client/rpc_transport_np.c b/source3/rpc_client/rpc_transport_np.c index 80ff384046..8b45cb4e9c 100644 --- a/source3/rpc_client/rpc_transport_np.c +++ b/source3/rpc_client/rpc_transport_np.c @@ -51,18 +51,19 @@ struct rpc_np_write_state { static void rpc_np_write_done(struct async_req *subreq); -static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) { struct rpc_transport_np_state *np_transport = talloc_get_type_abort( priv, struct rpc_transport_np_state); - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_np_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_np_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_np_write_state); + if (req == NULL) { return NULL; } state->size = size; @@ -75,37 +76,37 @@ static struct async_req *rpc_np_write_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_np_write_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_np_write_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_np_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_write_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_np_write_state *state = tevent_req_data( + req, struct rpc_np_write_state); NTSTATUS status; status = cli_write_andx_recv(subreq, &state->written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_np_write_recv(struct async_req *req, ssize_t *pwritten) +static NTSTATUS rpc_np_write_recv(struct tevent_req *req, ssize_t *pwritten) { - struct rpc_np_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_write_state); + struct rpc_np_write_state *state = tevent_req_data( + req, struct rpc_np_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *pwritten = state->written; @@ -120,18 +121,19 @@ struct rpc_np_read_state { static void rpc_np_read_done(struct async_req *subreq); -static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) { struct rpc_transport_np_state *np_transport = talloc_get_type_abort( priv, struct rpc_transport_np_state); - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_np_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_np_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_np_read_state); + if (req == NULL) { return NULL; } state->data = data; @@ -143,19 +145,19 @@ static struct async_req *rpc_np_read_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_np_read_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_np_read_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_np_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_read_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_np_read_state *state = tevent_req_data( + req, struct rpc_np_read_state); NTSTATUS status; uint8_t *rcvbuf; @@ -169,27 +171,27 @@ static void rpc_np_read_done(struct async_req *subreq) } if (!NT_STATUS_IS_OK(status)) { TALLOC_FREE(subreq); - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } if (state->received > state->size) { TALLOC_FREE(subreq); - async_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); + tevent_req_nterror(req, NT_STATUS_INVALID_NETWORK_RESPONSE); return; } memcpy(state->data, rcvbuf, state->received); - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_np_read_recv(struct async_req *req, ssize_t *preceived) +static NTSTATUS rpc_np_read_recv(struct tevent_req *req, ssize_t *preceived) { - struct rpc_np_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_read_state); + struct rpc_np_read_state *state = tevent_req_data( + req, struct rpc_np_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *preceived = state->received; @@ -204,19 +206,20 @@ struct rpc_np_trans_state { static void rpc_np_trans_done(struct async_req *subreq); -static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t data_len, - uint32_t max_rdata_len, - void *priv) +static struct tevent_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t data_len, + uint32_t max_rdata_len, + void *priv) { struct rpc_transport_np_state *np_transport = talloc_get_type_abort( priv, struct rpc_transport_np_state); - struct async_req *result, *subreq; + struct tevent_req *req; + struct async_req *subreq; struct rpc_np_trans_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_np_trans_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_np_trans_state); + if (req == NULL) { return NULL; } @@ -231,40 +234,40 @@ static struct async_req *rpc_np_trans_send(TALLOC_CTX *mem_ctx, goto fail; } subreq->async.fn = rpc_np_trans_done; - subreq->async.priv = result; - return result; + subreq->async.priv = req; + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_np_trans_done(struct async_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_np_trans_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_trans_state); + struct tevent_req *req = talloc_get_type_abort( + subreq->async.priv, struct tevent_req); + struct rpc_np_trans_state *state = tevent_req_data( + req, struct rpc_np_trans_state); NTSTATUS status; status = cli_trans_recv(subreq, state, NULL, NULL, NULL, NULL, &state->rdata, &state->rdata_len); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_np_trans_recv(struct async_req *req, TALLOC_CTX *mem_ctx, +static NTSTATUS rpc_np_trans_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, uint8_t **prdata, uint32_t *prdata_len) { - struct rpc_np_trans_state *state = talloc_get_type_abort( - req->private_data, struct rpc_np_trans_state); + struct rpc_np_trans_state *state = tevent_req_data( + req, struct rpc_np_trans_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *prdata = talloc_move(mem_ctx, &state->rdata); diff --git a/source3/rpc_client/rpc_transport_smbd.c b/source3/rpc_client/rpc_transport_smbd.c index bf4aa65dae..bde8d04208 100644 --- a/source3/rpc_client/rpc_transport_smbd.c +++ b/source3/rpc_client/rpc_transport_smbd.c @@ -432,20 +432,20 @@ struct rpc_smbd_write_state { ssize_t written; }; -static void rpc_smbd_write_done(struct async_req *subreq); +static void rpc_smbd_write_done(struct tevent_req *subreq); -static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) { struct rpc_transport_smbd_state *transp = talloc_get_type_abort( priv, struct rpc_transport_smbd_state); - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_smbd_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_smbd_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_write_state); + if (req == NULL) { return NULL; } state->sub_transp = transp->sub_transp; @@ -460,40 +460,38 @@ static struct async_req *rpc_smbd_write_send(TALLOC_CTX *mem_ctx, rpc_cli_smbd_stdout_reader, transp->conn) == NULL) { goto fail; } - - subreq->async.fn = rpc_smbd_write_done; - subreq->async.priv = result; - return result; + tevent_req_set_callback(subreq, rpc_smbd_write_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void rpc_smbd_write_done(struct async_req *subreq) +static void rpc_smbd_write_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_smbd_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_write_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_smbd_write_state *state = tevent_req_data( + req, struct rpc_smbd_write_state); NTSTATUS status; status = state->sub_transp->write_recv(subreq, &state->written); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_smbd_write_recv(struct async_req *req, ssize_t *pwritten) +static NTSTATUS rpc_smbd_write_recv(struct tevent_req *req, ssize_t *pwritten) { - struct rpc_smbd_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_write_state); + struct rpc_smbd_write_state *state = tevent_req_data( + req, struct rpc_smbd_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *pwritten = state->written; @@ -505,20 +503,20 @@ struct rpc_smbd_read_state { ssize_t received; }; -static void rpc_smbd_read_done(struct async_req *subreq); +static void rpc_smbd_read_done(struct tevent_req *subreq); -static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) { struct rpc_transport_smbd_state *transp = talloc_get_type_abort( priv, struct rpc_transport_smbd_state); - struct async_req *result, *subreq; + struct tevent_req *req, *subreq; struct rpc_smbd_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_smbd_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_smbd_read_state); + if (req == NULL) { return NULL; } state->sub_transp = transp->sub_transp; @@ -533,40 +531,37 @@ static struct async_req *rpc_smbd_read_send(TALLOC_CTX *mem_ctx, rpc_cli_smbd_stdout_reader, transp->conn) == NULL) { goto fail; } - - subreq->async.fn = rpc_smbd_read_done; - subreq->async.priv = result; - return result; - + tevent_req_set_callback(subreq, rpc_smbd_read_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } -static void rpc_smbd_read_done(struct async_req *subreq) +static void rpc_smbd_read_done(struct tevent_req *subreq) { - struct async_req *req = talloc_get_type_abort( - subreq->async.priv, struct async_req); - struct rpc_smbd_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_smbd_read_state *state = tevent_req_data( + req, struct rpc_smbd_read_state); NTSTATUS status; status = state->sub_transp->read_recv(subreq, &state->received); TALLOC_FREE(subreq); if (!NT_STATUS_IS_OK(status)) { - async_req_nterror(req, status); + tevent_req_nterror(req, status); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_smbd_read_recv(struct async_req *req, ssize_t *preceived) +static NTSTATUS rpc_smbd_read_recv(struct tevent_req *req, ssize_t *preceived) { - struct rpc_smbd_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_smbd_read_state); + struct rpc_smbd_read_state *state = tevent_req_data( + req, struct rpc_smbd_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *preceived = state->received; diff --git a/source3/rpc_client/rpc_transport_sock.c b/source3/rpc_client/rpc_transport_sock.c index b1d9d8fbe1..570d792c9c 100644 --- a/source3/rpc_client/rpc_transport_sock.c +++ b/source3/rpc_client/rpc_transport_sock.c @@ -41,19 +41,18 @@ struct rpc_sock_read_state { static void rpc_sock_read_done(struct tevent_req *subreq); -static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + uint8_t *data, size_t size, + void *priv) { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_sock_read_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_sock_read_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_sock_read_state); + if (req == NULL) { return NULL; } @@ -61,36 +60,36 @@ static struct async_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx, if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, rpc_sock_read_done, result); - return result; + tevent_req_set_callback(subreq, rpc_sock_read_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_sock_read_done(struct tevent_req *subreq) { - struct async_req *req = - tevent_req_callback_data(subreq, struct async_req); - struct rpc_sock_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_read_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_sock_read_state *state = tevent_req_data( + req, struct rpc_sock_read_state); int err; state->received = async_recv_recv(subreq, &err); if (state->received == -1) { - async_req_nterror(req, map_nt_error_from_unix(err)); + tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_sock_read_recv(struct async_req *req, ssize_t *preceived) +static NTSTATUS rpc_sock_read_recv(struct tevent_req *req, ssize_t *preceived) { - struct rpc_sock_read_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_read_state); + struct rpc_sock_read_state *state = tevent_req_data( + req, struct rpc_sock_read_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *preceived = state->received; @@ -103,55 +102,54 @@ struct rpc_sock_write_state { static void rpc_sock_write_done(struct tevent_req *subreq); -static struct async_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, - struct event_context *ev, - const uint8_t *data, size_t size, - void *priv) +static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx, + struct event_context *ev, + const uint8_t *data, size_t size, + void *priv) { struct rpc_transport_sock_state *sock_transp = talloc_get_type_abort( priv, struct rpc_transport_sock_state); - struct async_req *result; - struct tevent_req *subreq; + struct tevent_req *req, *subreq; struct rpc_sock_write_state *state; - if (!async_req_setup(mem_ctx, &result, &state, - struct rpc_sock_write_state)) { + req = tevent_req_create(mem_ctx, &state, struct rpc_sock_write_state); + if (req == NULL) { return NULL; } subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0); if (subreq == NULL) { goto fail; } - tevent_req_set_callback(subreq, rpc_sock_write_done, result); - return result; + tevent_req_set_callback(subreq, rpc_sock_write_done, req); + return req; fail: - TALLOC_FREE(result); + TALLOC_FREE(req); return NULL; } static void rpc_sock_write_done(struct tevent_req *subreq) { - struct async_req *req = - tevent_req_callback_data(subreq, struct async_req); - struct rpc_sock_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_write_state); + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct rpc_sock_write_state *state = tevent_req_data( + req, struct rpc_sock_write_state); int err; state->sent = async_send_recv(subreq, &err); if (state->sent == -1) { - async_req_nterror(req, map_nt_error_from_unix(err)); + tevent_req_nterror(req, map_nt_error_from_unix(err)); return; } - async_req_done(req); + tevent_req_done(req); } -static NTSTATUS rpc_sock_write_recv(struct async_req *req, ssize_t *psent) +static NTSTATUS rpc_sock_write_recv(struct tevent_req *req, ssize_t *psent) { - struct rpc_sock_write_state *state = talloc_get_type_abort( - req->private_data, struct rpc_sock_write_state); + struct rpc_sock_write_state *state = tevent_req_data( + req, struct rpc_sock_write_state); NTSTATUS status; - if (async_req_is_nterror(req, &status)) { + if (tevent_req_is_nterror(req, &status)) { return status; } *psent = state->sent; diff --git a/source3/rpc_parse/parse_misc.c b/source3/rpc_parse/parse_misc.c index 8b4135a1e8..1ea4ecf46f 100644 --- a/source3/rpc_parse/parse_misc.c +++ b/source3/rpc_parse/parse_misc.c @@ -101,44 +101,6 @@ bool make_systemtime(SYSTEMTIME *systime, struct tm *unixtime) } /******************************************************************* - Reads or writes a DOM_SID structure. -********************************************************************/ - -bool smb_io_dom_sid(const char *desc, DOM_SID *sid, prs_struct *ps, int depth) -{ - int i; - - if (sid == NULL) - return False; - - prs_debug(ps, depth, desc, "smb_io_dom_sid"); - depth++; - - if(!prs_uint8 ("sid_rev_num", ps, depth, &sid->sid_rev_num)) - return False; - - if(!prs_uint8 ("num_auths ", ps, depth, (uint8 *)&sid->num_auths)) - return False; - - for (i = 0; i < 6; i++) - { - fstring tmp; - slprintf(tmp, sizeof(tmp) - 1, "id_auth[%d] ", i); - if(!prs_uint8 (tmp, ps, depth, &sid->id_auth[i])) - return False; - } - - /* oops! XXXX should really issue a warning here... */ - if (sid->num_auths > MAXSUBAUTHS) - sid->num_auths = MAXSUBAUTHS; - - if(!prs_uint32s(False, "sub_auths ", ps, depth, sid->sub_auths, sid->num_auths)) - return False; - - return True; -} - -/******************************************************************* Reads or writes a struct GUID ********************************************************************/ @@ -167,25 +129,6 @@ bool smb_io_uuid(const char *desc, struct GUID *uuid, } /******************************************************************* - Inits a UNISTR structure. -********************************************************************/ - -void init_unistr(UNISTR *str, const char *buf) -{ - size_t len; - - if (buf == NULL) { - str->buffer = NULL; - return; - } - - len = rpcstr_push_talloc(talloc_tos(), &str->buffer, buf); - if (len == (size_t)-1) { - str->buffer = NULL; - } -} - -/******************************************************************* Inits a UNISTR2 structure. ********************************************************************/ diff --git a/source3/rpc_parse/parse_sec.c b/source3/rpc_parse/parse_sec.c deleted file mode 100644 index 91d8591a05..0000000000 --- a/source3/rpc_parse/parse_sec.c +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Unix SMB/Netbios implementation. - * Version 1.9. - * RPC Pipe client / server routines - * Copyright (C) Andrew Tridgell 1992-1998, - * Copyright (C) Jeremy R. Allison 1995-2005. - * Copyright (C) Luke Kenneth Casson Leighton 1996-1998, - * Copyright (C) Paul Ashton 1997-1998. - * - * 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" - -#undef DBGC_CLASS -#define DBGC_CLASS DBGC_RPC_PARSE - -/******************************************************************* - Reads or writes a SEC_ACE structure. -********************************************************************/ - -static bool sec_io_ace(const char *desc, SEC_ACE *psa, prs_struct *ps, - int depth) -{ - uint32 old_offset; - uint32 offset_ace_size; - uint8 type; - - if (psa == NULL) - return False; - - prs_debug(ps, depth, desc, "sec_io_ace"); - depth++; - - old_offset = prs_offset(ps); - - if (MARSHALLING(ps)) { - type = (uint8)psa->type; - } - - if(!prs_uint8("type ", ps, depth, &type)) - return False; - - if (UNMARSHALLING(ps)) { - psa->type = (enum security_ace_type)type; - } - - if(!prs_uint8("flags", ps, depth, &psa->flags)) - return False; - - if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_ace_size)) - return False; - - if(!prs_uint32("access_mask", ps, depth, &psa->access_mask)) - return False; - - /* check whether object access is present */ - if (!sec_ace_object(psa->type)) { - if (!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) - return False; - } else { - if (!prs_uint32("obj_flags", ps, depth, &psa->object.object.flags)) - return False; - - if (psa->object.object.flags & SEC_ACE_OBJECT_TYPE_PRESENT) - if (!smb_io_uuid("obj_guid", &psa->object.object.type.type, ps,depth)) - return False; - - if (psa->object.object.flags & SEC_ACE_INHERITED_OBJECT_TYPE_PRESENT) - if (!smb_io_uuid("inh_guid", &psa->object.object.inherited_type.inherited_type, ps,depth)) - return False; - - if(!smb_io_dom_sid("trustee ", &psa->trustee , ps, depth)) - return False; - } - - /* Theorectically an ACE can have a size greater than the - sum of its components. When marshalling, pad with extra null bytes up to the - correct size. */ - - if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) { - uint32 extra_len = psa->size - (prs_offset(ps) - old_offset); - uint32 i; - uint8 c = 0; - - for (i = 0; i < extra_len; i++) { - if (!prs_uint8("ace extra space", ps, depth, &c)) - return False; - } - } - - if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_ace_size, old_offset)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SEC_ACL structure. - - First of the xx_io_xx functions that allocates its data structures - for you as it reads them. -********************************************************************/ - -static bool sec_io_acl(const char *desc, SEC_ACL **ppsa, prs_struct *ps, - int depth) -{ - unsigned int i; - uint32 old_offset; - uint32 offset_acl_size; - SEC_ACL *psa; - uint16 revision; - - /* - * Note that the size is always a multiple of 4 bytes due to the - * nature of the data structure. Therefore the prs_align() calls - * have been removed as they through us off when doing two-layer - * marshalling such as in the printing code (RPC_BUFFER). --jerry - */ - - if (ppsa == NULL) - return False; - - psa = *ppsa; - - if(UNMARSHALLING(ps) && psa == NULL) { - /* - * This is a read and we must allocate the stuct to read into. - */ - if((psa = PRS_ALLOC_MEM(ps, SEC_ACL, 1)) == NULL) - return False; - *ppsa = psa; - } - - prs_debug(ps, depth, desc, "sec_io_acl"); - depth++; - - old_offset = prs_offset(ps); - - if (MARSHALLING(ps)) { - revision = (uint16)psa->revision; - } - - if(!prs_uint16("revision", ps, depth, &revision)) - return False; - - if (UNMARSHALLING(ps)) { - psa->revision = (enum security_acl_revision)revision; - } - - if(!prs_uint16_pre("size ", ps, depth, &psa->size, &offset_acl_size)) - return False; - - if(!prs_uint32("num_aces ", ps, depth, &psa->num_aces)) - return False; - - if (UNMARSHALLING(ps)) { - if (psa->num_aces) { - if((psa->aces = PRS_ALLOC_MEM(ps, SEC_ACE, psa->num_aces)) == NULL) - return False; - } else { - psa->aces = NULL; - } - } - - for (i = 0; i < psa->num_aces; i++) { - fstring tmp; - slprintf(tmp, sizeof(tmp)-1, "ace_list[%02d]: ", i); - if(!sec_io_ace(tmp, &psa->aces[i], ps, depth)) - return False; - } - - /* Theorectically an ACL can have a size greater than the - sum of its components. When marshalling, pad with extra null bytes up to the - correct size. */ - - if (MARSHALLING(ps) && (psa->size > prs_offset(ps) - old_offset)) { - uint32 extra_len = psa->size - (prs_offset(ps) - old_offset); - uint8 c = 0; - - for (i = 0; i < extra_len; i++) { - if (!prs_uint8("acl extra space", ps, depth, &c)) - return False; - } - } - - if(!prs_uint16_post("size ", ps, depth, &psa->size, offset_acl_size, old_offset)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SEC_DESC structure. - If reading and the *ppsd = NULL, allocates the structure. -********************************************************************/ - -bool sec_io_desc(const char *desc, SEC_DESC **ppsd, prs_struct *ps, int depth) -{ - uint32 old_offset; - uint32 max_offset = 0; /* after we're done, move offset to end */ - uint32 tmp_offset = 0; - uint32 off_sacl, off_dacl, off_owner_sid, off_grp_sid; - uint16 revision; - - SEC_DESC *psd; - - if (ppsd == NULL) - return False; - - psd = *ppsd; - - if (psd == NULL) { - if(UNMARSHALLING(ps)) { - if((psd = PRS_ALLOC_MEM(ps,SEC_DESC,1)) == NULL) - return False; - *ppsd = psd; - } else { - /* Marshalling - just ignore. */ - return True; - } - } - - prs_debug(ps, depth, desc, "sec_io_desc"); - depth++; - - /* start of security descriptor stored for back-calc offset purposes */ - old_offset = prs_offset(ps); - - if (MARSHALLING(ps)) { - revision = (uint16)psd->revision; - } - - if(!prs_uint16("revision", ps, depth, &revision)) - return False; - - if (UNMARSHALLING(ps)) { - psd->revision = (enum security_descriptor_revision)revision; - } - - if(!prs_uint16("type ", ps, depth, &psd->type)) - return False; - - if (MARSHALLING(ps)) { - uint32 offset = SEC_DESC_HEADER_SIZE; - - /* - * Work out the offsets here, as we write it out. - */ - - if (psd->sacl != NULL) { - off_sacl = offset; - offset += psd->sacl->size; - } else { - off_sacl = 0; - } - - if (psd->dacl != NULL) { - off_dacl = offset; - offset += psd->dacl->size; - } else { - off_dacl = 0; - } - - if (psd->owner_sid != NULL) { - off_owner_sid = offset; - offset += ndr_size_dom_sid(psd->owner_sid, NULL, 0); - } else { - off_owner_sid = 0; - } - - if (psd->group_sid != NULL) { - off_grp_sid = offset; - offset += ndr_size_dom_sid(psd->group_sid, NULL, 0); - } else { - off_grp_sid = 0; - } - } - - if(!prs_uint32("off_owner_sid", ps, depth, &off_owner_sid)) - return False; - - if(!prs_uint32("off_grp_sid ", ps, depth, &off_grp_sid)) - return False; - - if(!prs_uint32("off_sacl ", ps, depth, &off_sacl)) - return False; - - if(!prs_uint32("off_dacl ", ps, depth, &off_dacl)) - return False; - - max_offset = MAX(max_offset, prs_offset(ps)); - - if (off_owner_sid != 0) { - - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_owner_sid)) - return False; - - if (UNMARSHALLING(ps)) { - /* reading */ - if((psd->owner_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL) - return False; - } - - if(!smb_io_dom_sid("owner_sid ", psd->owner_sid , ps, depth)) - return False; - - max_offset = MAX(max_offset, prs_offset(ps)); - - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if (psd->group_sid != 0) { - - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_grp_sid)) - return False; - - if (UNMARSHALLING(ps)) { - /* reading */ - if((psd->group_sid = PRS_ALLOC_MEM(ps,DOM_SID,1)) == NULL) - return False; - } - - if(!smb_io_dom_sid("grp_sid", psd->group_sid, ps, depth)) - return False; - - max_offset = MAX(max_offset, prs_offset(ps)); - - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if ((psd->type & SEC_DESC_SACL_PRESENT) && off_sacl) { - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_sacl)) - return False; - if(!sec_io_acl("sacl", &psd->sacl, ps, depth)) - return False; - max_offset = MAX(max_offset, prs_offset(ps)); - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if ((psd->type & SEC_DESC_DACL_PRESENT) && off_dacl != 0) { - tmp_offset = prs_offset(ps); - if(!prs_set_offset(ps, old_offset + off_dacl)) - return False; - if(!sec_io_acl("dacl", &psd->dacl, ps, depth)) - return False; - max_offset = MAX(max_offset, prs_offset(ps)); - if (!prs_set_offset(ps,tmp_offset)) - return False; - } - - if(!prs_set_offset(ps, max_offset)) - return False; - - return True; -} - -/******************************************************************* - Reads or writes a SEC_DESC_BUF structure. -********************************************************************/ - -bool sec_io_desc_buf(const char *desc, SEC_DESC_BUF **ppsdb, prs_struct *ps, int depth) -{ - uint32 off_len; - uint32 off_max_len; - uint32 old_offset; - uint32 size; - uint32 len; - SEC_DESC_BUF *psdb; - uint32 ptr; - - if (ppsdb == NULL) - return False; - - psdb = *ppsdb; - - if (UNMARSHALLING(ps) && psdb == NULL) { - if((psdb = PRS_ALLOC_MEM(ps,SEC_DESC_BUF,1)) == NULL) - return False; - *ppsdb = psdb; - } - - prs_debug(ps, depth, desc, "sec_io_desc_buf"); - depth++; - - if(!prs_align(ps)) - return False; - - if(!prs_uint32_pre("max_len", ps, depth, &psdb->sd_size, &off_max_len)) - return False; - - ptr = 1; - if(!prs_uint32 ("ptr ", ps, depth, &ptr)) - return False; - - len = ndr_size_security_descriptor(psdb->sd, NULL, 0); - if(!prs_uint32_pre("len ", ps, depth, &len, &off_len)) - return False; - - old_offset = prs_offset(ps); - - /* reading, length is non-zero; writing, descriptor is non-NULL */ - if ((UNMARSHALLING(ps) && psdb->sd_size != 0) || (MARSHALLING(ps) && psdb->sd != NULL)) { - if(!sec_io_desc("sec ", &psdb->sd, ps, depth)) - return False; - } - - if(!prs_align(ps)) - return False; - - size = prs_offset(ps) - old_offset; - if(!prs_uint32_post("max_len", ps, depth, &psdb->sd_size, off_max_len, size == 0 ? psdb->sd_size : size)) - return False; - - if(!prs_uint32_post("len ", ps, depth, &len, off_len, size)) - return False; - - return True; -} diff --git a/source3/rpc_server/srv_lsa_nt.c b/source3/rpc_server/srv_lsa_nt.c index ed54c3a86e..5fdcaf2d4a 100644 --- a/source3/rpc_server/srv_lsa_nt.c +++ b/source3/rpc_server/srv_lsa_nt.c @@ -827,6 +827,10 @@ NTSTATUS _lsa_LookupSids(pipes_struct *p, &names, &mapped_count); + if (NT_STATUS_IS_ERR(status)) { + return status; + } + /* Convert from lsa_TranslatedName2 to lsa_TranslatedName */ names_out = TALLOC_ARRAY(p->mem_ctx, struct lsa_TranslatedName, num_sids); diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index 503e22b653..ffb7dde1c3 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -1383,7 +1383,7 @@ struct tevent_req *np_read_send(TALLOC_CTX *mem_ctx, struct event_context *ev, static void np_read_trigger(struct tevent_req *req, void *private_data) { - struct np_read_state *state = tevent_req_callback_data( + struct np_read_state *state = tevent_req_data( req, struct np_read_state); struct tevent_req *subreq; diff --git a/source3/rpc_server/srv_samr_nt.c b/source3/rpc_server/srv_samr_nt.c index dcbd0963c4..c60d904b18 100644 --- a/source3/rpc_server/srv_samr_nt.c +++ b/source3/rpc_server/srv_samr_nt.c @@ -3636,12 +3636,7 @@ static NTSTATUS set_user_info_18(struct samr_UserInfo18 *id18, pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); } - if (id18->password_expired) { - pdb_set_pass_last_set_time(pwd, 0, PDB_CHANGED); - } else { - /* FIXME */ - pdb_set_pass_last_set_time(pwd, time(NULL), PDB_CHANGED); - } + copy_id18_to_sam_passwd(pwd, id18); return pdb_update_sam_account(pwd); } @@ -3848,23 +3843,16 @@ static NTSTATUS set_user_info_23(TALLOC_CTX *mem_ctx, set_user_info_pw ********************************************************************/ -static bool set_user_info_pw(uint8 *pass, struct samu *pwd, - int level) +static bool set_user_info_pw(uint8 *pass, struct samu *pwd) { uint32 len = 0; char *plaintext_buf = NULL; uint32 acct_ctrl; - time_t last_set_time; - enum pdb_value_state last_set_state; DEBUG(5, ("Attempting administrator password change for user %s\n", pdb_get_username(pwd))); acct_ctrl = pdb_get_acct_ctrl(pwd); - /* we need to know if it's expired, because this is an admin change, not a - user change, so it's still expired when we're done */ - last_set_state = pdb_get_init_flags(pwd, PDB_PASSLASTSET); - last_set_time = pdb_get_pass_last_set_time(pwd); if (!decode_pw_buffer(talloc_tos(), pass, @@ -3907,29 +3895,38 @@ static bool set_user_info_pw(uint8 *pass, struct samu *pwd, memset(plaintext_buf, '\0', strlen(plaintext_buf)); - /* - * A level 25 change does reset the pwdlastset field, a level 24 - * change does not. I know this is probably not the full story, but - * it is needed to make XP join LDAP correctly, without it the later - * auth2 check can fail with PWD_MUST_CHANGE. - */ - if (level != 25) { - /* - * restore last set time as this is an admin change, not a - * user pw change - */ - pdb_set_pass_last_set_time (pwd, last_set_time, - last_set_state); + DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n")); + + return True; +} + +/******************************************************************* + set_user_info_24 + ********************************************************************/ + +static NTSTATUS set_user_info_24(TALLOC_CTX *mem_ctx, + struct samr_UserInfo24 *id24, + struct samu *pwd) +{ + NTSTATUS status; + + if (id24 == NULL) { + DEBUG(5, ("set_user_info_24: NULL id24\n")); + return NT_STATUS_INVALID_PARAMETER; } - DEBUG(5,("set_user_info_pw: pdb_update_pwd()\n")); + if (!set_user_info_pw(id24->password.data, pwd)) { + return NT_STATUS_WRONG_PASSWORD; + } - /* update the SAMBA password */ - if(!NT_STATUS_IS_OK(pdb_update_sam_account(pwd))) { - return False; + copy_id24_to_sam_passwd(pwd, id24); + + status = pdb_update_sam_account(pwd); + if (!NT_STATUS_IS_OK(status)) { + return status; } - return True; + return NT_STATUS_OK; } /******************************************************************* @@ -3955,6 +3952,14 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, return NT_STATUS_ACCESS_DENIED; } + if ((id25->info.fields_present & SAMR_FIELD_NT_PASSWORD_PRESENT) || + (id25->info.fields_present & SAMR_FIELD_LM_PASSWORD_PRESENT)) { + + if (!set_user_info_pw(id25->password.data, pwd)) { + return NT_STATUS_WRONG_PASSWORD; + } + } + copy_id25_to_sam_passwd(pwd, id25); /* write the change out */ @@ -3981,6 +3986,36 @@ static NTSTATUS set_user_info_25(TALLOC_CTX *mem_ctx, } /******************************************************************* + set_user_info_26 + ********************************************************************/ + +static NTSTATUS set_user_info_26(TALLOC_CTX *mem_ctx, + struct samr_UserInfo26 *id26, + struct samu *pwd) +{ + NTSTATUS status; + + if (id26 == NULL) { + DEBUG(5, ("set_user_info_26: NULL id26\n")); + return NT_STATUS_INVALID_PARAMETER; + } + + if (!set_user_info_pw(id26->password.data, pwd)) { + return NT_STATUS_WRONG_PASSWORD; + } + + copy_id26_to_sam_passwd(pwd, id26); + + status = pdb_update_sam_account(pwd); + if (!NT_STATUS_IS_OK(status)) { + return status; + } + + return NT_STATUS_OK; +} + + +/******************************************************************* samr_SetUserInfo ********************************************************************/ @@ -4139,10 +4174,8 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, dump_data(100, info->info24.password.data, 516); - if (!set_user_info_pw(info->info24.password.data, pwd, - switch_value)) { - status = NT_STATUS_WRONG_PASSWORD; - } + status = set_user_info_24(p->mem_ctx, + &info->info24, pwd); break; case 25: @@ -4157,13 +4190,6 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, status = set_user_info_25(p->mem_ctx, &info->info25, pwd); - if (!NT_STATUS_IS_OK(status)) { - goto done; - } - if (!set_user_info_pw(info->info25.password.data, pwd, - switch_value)) { - status = NT_STATUS_WRONG_PASSWORD; - } break; case 26: @@ -4176,18 +4202,14 @@ NTSTATUS _samr_SetUserInfo(pipes_struct *p, dump_data(100, info->info26.password.data, 516); - if (!set_user_info_pw(info->info26.password.data, pwd, - switch_value)) { - status = NT_STATUS_WRONG_PASSWORD; - } + status = set_user_info_26(p->mem_ctx, + &info->info26, pwd); break; default: status = NT_STATUS_INVALID_INFO_CLASS; } - done: - TALLOC_FREE(pwd); if (has_enough_rights) { diff --git a/source3/rpc_server/srv_samr_util.c b/source3/rpc_server/srv_samr_util.c index ef588aed1a..068156054f 100644 --- a/source3/rpc_server/srv_samr_util.c +++ b/source3/rpc_server/srv_samr_util.c @@ -36,6 +36,27 @@ ((s1) && (s2) && (strcmp((s1), (s2)) != 0)) /************************************************************* + Copies a struct samr_UserInfo18 to a struct samu +**************************************************************/ + +void copy_id18_to_sam_passwd(struct samu *to, + struct samr_UserInfo18 *from) +{ + struct samr_UserInfo21 i; + + if (from == NULL || to == NULL) { + return; + } + + ZERO_STRUCT(i); + + i.fields_present = SAMR_FIELD_EXPIRED_FLAG; + i.password_expired = from->password_expired; + + copy_id21_to_sam_passwd("INFO_18", to, &i); +} + +/************************************************************* Copies a struct samr_UserInfo20 to a struct samu **************************************************************/ @@ -336,7 +357,7 @@ void copy_id21_to_sam_passwd(const char *log_prefix, if (from->fields_present & SAMR_FIELD_EXPIRED_FLAG) { DEBUG(10,("%s SAMR_FIELD_EXPIRED_FLAG: %02X\n", l, from->password_expired)); - if (from->password_expired == PASS_MUST_CHANGE_AT_NEXT_LOGON) { + if (from->password_expired != 0) { pdb_set_pass_last_set_time(to, 0, PDB_CHANGED); } else { /* A subtlety here: some windows commands will @@ -345,9 +366,27 @@ void copy_id21_to_sam_passwd(const char *log_prefix, in these caess. "net user /dom <user> /active:y" for example, to clear an autolocked acct. We must check to see if it's expired first. jmcd */ + + uint32_t pwd_max_age = 0; + time_t now = time(NULL); + + pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &pwd_max_age); + + if (pwd_max_age == (uint32_t)-1 || pwd_max_age == 0) { + pwd_max_age = get_time_t_max(); + } + stored_time = pdb_get_pass_last_set_time(to); - if (stored_time == 0) - pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED); + + /* we will only *set* a pwdlastset date when + a) the last pwdlastset time was 0 (user was forced to + change password). + b) the users password has not expired. gd. */ + + if ((stored_time == 0) || + ((now - stored_time) > pwd_max_age)) { + pdb_set_pass_last_set_time(to, now, PDB_CHANGED); + } } } } @@ -368,6 +407,27 @@ void copy_id23_to_sam_passwd(struct samu *to, } /************************************************************* + Copies a struct samr_UserInfo24 to a struct samu +**************************************************************/ + +void copy_id24_to_sam_passwd(struct samu *to, + struct samr_UserInfo24 *from) +{ + struct samr_UserInfo21 i; + + if (from == NULL || to == NULL) { + return; + } + + ZERO_STRUCT(i); + + i.fields_present = SAMR_FIELD_EXPIRED_FLAG; + i.password_expired = from->password_expired; + + copy_id21_to_sam_passwd("INFO_24", to, &i); +} + +/************************************************************* Copies a struct samr_UserInfo25 to a struct samu **************************************************************/ @@ -380,3 +440,24 @@ void copy_id25_to_sam_passwd(struct samu *to, copy_id21_to_sam_passwd("INFO_25", to, &from->info); } + +/************************************************************* + Copies a struct samr_UserInfo26 to a struct samu +**************************************************************/ + +void copy_id26_to_sam_passwd(struct samu *to, + struct samr_UserInfo26 *from) +{ + struct samr_UserInfo21 i; + + if (from == NULL || to == NULL) { + return; + } + + ZERO_STRUCT(i); + + i.fields_present = SAMR_FIELD_EXPIRED_FLAG; + i.password_expired = from->password_expired; + + copy_id21_to_sam_passwd("INFO_26", to, &i); +} diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index ab15e5c5f6..15c137a88c 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -66,13 +66,13 @@ typedef struct _counter_printer_0 { struct _counter_printer_0 *prev; int snum; - uint32 counter; + uint32_t counter; } counter_printer_0; static counter_printer_0 *counter_list; static struct rpc_pipe_client *notify_cli_pipe; /* print notify back-channel pipe handle*/ -static uint32 smb_connections=0; +static uint32_t smb_connections = 0; /* in printing/nt_printing.c */ @@ -186,7 +186,7 @@ static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle /* Tell the connections db we're no longer interested in * printer notify messages. */ - register_message_flags( False, FLAG_MSG_PRINT_NOTIFY ); + register_message_flags(false, FLAG_MSG_PRINT_NOTIFY); } smb_connections--; @@ -198,7 +198,7 @@ static void srv_spoolss_replycloseprinter(int snum, struct policy_handle *handle static int printer_entry_destructor(Printer_entry *Printer) { - if (Printer->notify.client_connected==True) { + if (Printer->notify.client_connected == true) { int snum = -1; if ( Printer->printer_type == SPLHND_SERVER) { @@ -217,7 +217,7 @@ static int printer_entry_destructor(Printer_entry *Printer) Printer->notify.localmachine[0]='\0'; Printer->notify.printerlocal=0; TALLOC_FREE(Printer->notify.option); - Printer->notify.client_connected=False; + Printer->notify.client_connected = false; free_nt_devicemode( &Printer->nt_devmode ); free_a_printer( &Printer->printer_info, 2 ); @@ -255,12 +255,12 @@ static bool close_printer_handle(pipes_struct *p, struct policy_handle *hnd) if (!Printer) { DEBUG(2,("close_printer_handle: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); - return False; + return false; } close_policy_hnd(p, hnd); - return True; + return true; } /**************************************************************************** @@ -273,7 +273,7 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh char *command = NULL; int ret; SE_PRIV se_printop = SE_PRINT_OPERATOR; - bool is_print_op = False; + bool is_print_op = false; /* can't fail if we don't try */ @@ -315,7 +315,7 @@ WERROR delete_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *sh return WERR_BADFID; /* What to return here? */ /* go ahead and re-read the services immediately */ - reload_services( False ); + reload_services(false); if ( lp_servicenumber( sharename ) < 0 ) return WERR_ACCESS_DENIED; @@ -373,7 +373,7 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, if (!Printer) { DEBUG(2,("get_printer_snum: Invalid handle (%s:%u:%u)\n", OUR_HANDLE(hnd))); - return False; + return false; } switch (Printer->printer_type) { @@ -382,9 +382,9 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, *number = print_queue_snum(Printer->sharename); return (*number != -1); case SPLHND_SERVER: - return False; + return false; default: - return False; + return false; } } @@ -393,13 +393,13 @@ static bool get_printer_snum(pipes_struct *p, struct policy_handle *hnd, Check if it's \\server or \\server\printer ****************************************************************************/ -static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename) +static bool set_printer_hnd_printertype(Printer_entry *Printer, const char *handlename) { DEBUG(3,("Setting printer type=%s\n", handlename)); if ( strlen(handlename) < 3 ) { DEBUGADD(4,("A print server must have at least 1 char ! %s\n", handlename)); - return False; + return false; } /* it's a print server */ @@ -413,7 +413,7 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename Printer->printer_type = SPLHND_PRINTER; } - return True; + return true; } /**************************************************************************** @@ -423,20 +423,21 @@ static bool set_printer_hnd_printertype(Printer_entry *Printer, char *handlename XcvDataPort() interface. ****************************************************************************/ -static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) +static bool set_printer_hnd_name(Printer_entry *Printer, const char *handlename) { int snum; int n_services=lp_numservices(); char *aprinter, *printername; const char *servername; fstring sname; - bool found=False; + bool found = false; NT_PRINTER_INFO_LEVEL *printer = NULL; WERROR result; - DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, (unsigned long)strlen(handlename))); + DEBUG(4,("Setting printer name=%s (len=%lu)\n", handlename, + (unsigned long)strlen(handlename))); - aprinter = handlename; + aprinter = CONST_DISCARD(char *, handlename); if ( *handlename == '\\' ) { servername = canon_servername(handlename); if ( (aprinter = strchr_m( servername, '\\' )) != NULL ) { @@ -450,15 +451,15 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) /* save the servername to fill in replies on this handle */ if ( !is_myname_or_ipaddr( servername ) ) - return False; + return false; fstrcpy( Printer->servername, servername ); if ( Printer->printer_type == SPLHND_SERVER ) - return True; + return true; if ( Printer->printer_type != SPLHND_PRINTER ) - return False; + return false; DEBUGADD(5, ("searching for [%s]\n", aprinter )); @@ -467,12 +468,12 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( strequal( aprinter, SPL_XCV_MONITOR_TCPMON ) ) { Printer->printer_type = SPLHND_PORTMON_TCP; fstrcpy(sname, SPL_XCV_MONITOR_TCPMON); - found = True; + found = true; } else if ( strequal( aprinter, SPL_XCV_MONITOR_LOCALMON ) ) { Printer->printer_type = SPLHND_PORTMON_LOCAL; fstrcpy(sname, SPL_XCV_MONITOR_LOCALMON); - found = True; + found = true; } /* Search all sharenames first as this is easier than pulling @@ -490,7 +491,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) fstrcpy(sname, lp_servicename(snum)); if ( strequal( aprinter, sname ) ) { - found = True; + found = true; break; } @@ -528,7 +529,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( strequal(printername, aprinter) ) { free_a_printer( &printer, 2); - found = True; + found = true; break; } @@ -541,14 +542,14 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) if ( !found ) { DEBUGADD(4,("Printer not found\n")); - return False; + return false; } DEBUGADD(4,("set_printer_hnd_name: Printer found: %s -> %s\n", aprinter, sname)); fstrcpy(Printer->sharename, sname); - return True; + return true; } /**************************************************************************** @@ -556,7 +557,7 @@ static bool set_printer_hnd_name(Printer_entry *Printer, char *handlename) ****************************************************************************/ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, - char *name, uint32_t access_granted) + const char *name, uint32_t access_granted) { Printer_entry *new_printer; @@ -570,7 +571,7 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, if (!create_policy_hnd(p, hnd, new_printer)) { TALLOC_FREE(new_printer); - return False; + return false; } /* Add to the internal list. */ @@ -580,19 +581,19 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, if (!set_printer_hnd_printertype(new_printer, name)) { close_printer_handle(p, hnd); - return False; + return false; } if (!set_printer_hnd_name(new_printer, name)) { close_printer_handle(p, hnd); - return False; + return false; } new_printer->access_granted = access_granted; DEBUG(5, ("%d printer handles active\n", (int)p->pipe_handles->count )); - return True; + return true; } /*************************************************************************** @@ -600,17 +601,17 @@ static bool open_printer_hnd(pipes_struct *p, struct policy_handle *hnd, given by (notify_type, notify_field). **************************************************************************/ -static bool is_monitoring_event_flags(uint32 flags, uint16 notify_type, - uint16 notify_field) +static bool is_monitoring_event_flags(uint32_t flags, uint16_t notify_type, + uint16_t notify_field) { - return True; + return true; } -static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, - uint16 notify_field) +static bool is_monitoring_event(Printer_entry *p, uint16_t notify_type, + uint16_t notify_field) { struct spoolss_NotifyOption *option = p->notify.option; - uint32 i, j; + uint32_t i, j; /* * Flags should always be zero when the change notify @@ -620,7 +621,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, */ if (!option) { - return False; + return false; } if (p->notify.flags) @@ -638,7 +639,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, for (j = 0; j < option->types[i].count; j++) { if (option->types[i].fields[j].field == notify_field) { - return True; + return true; } } } @@ -646,7 +647,7 @@ static bool is_monitoring_event(Printer_entry *p, uint16 notify_type, DEBUG(10, ("Open handle for \\\\%s\\%s is not monitoring 0x%02x/0x%02x\n", p->servername, p->sharename, notify_type, notify_field)); - return False; + return false; } #define SETUP_SPOOLSS_NOTIFY_DATA_INTEGER(_data, _integer) \ @@ -849,7 +850,7 @@ static TALLOC_CTX* notify_ctr_getctx( SPOOLSS_NOTIFY_MSG_CTR *ctr ) /*********************************************************************** **********************************************************************/ -static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) +static SPOOLSS_NOTIFY_MSG_GROUP* notify_ctr_getgroup( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx ) { if ( !ctr || !ctr->msg_groups ) return NULL; @@ -940,7 +941,7 @@ static int notify_msg_ctr_addmsg( SPOOLSS_NOTIFY_MSG_CTR *ctr, SPOOLSS_NOTIFY_MS back registered **********************************************************************/ -static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx ) +static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32_t idx ) { Printer_entry *p; TALLOC_CTX *mem_ctx = notify_ctr_getctx( ctr ); @@ -1113,23 +1114,23 @@ done: static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, void *buf, size_t len ) { - uint32 tv_sec, tv_usec; + uint32_t tv_sec, tv_usec; size_t offset = 0; /* Unpack message */ - offset += tdb_unpack((uint8 *)buf + offset, len - offset, "f", + offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "f", msg->printer); - offset += tdb_unpack((uint8 *)buf + offset, len - offset, "ddddddd", + offset += tdb_unpack((uint8_t *)buf + offset, len - offset, "ddddddd", &tv_sec, &tv_usec, &msg->type, &msg->field, &msg->id, &msg->len, &msg->flags); if (msg->len == 0) - tdb_unpack((uint8 *)buf + offset, len - offset, "dd", + tdb_unpack((uint8_t *)buf + offset, len - offset, "dd", &msg->notify.value[0], &msg->notify.value[1]); else - tdb_unpack((uint8 *)buf + offset, len - offset, "B", + tdb_unpack((uint8_t *)buf + offset, len - offset, "B", &msg->len, &msg->notify.data); DEBUG(3, ("notify2_unpack_msg: got NOTIFY2 message for printer %s, jobid %u type %d, field 0x%02x, flags 0x%04x\n", @@ -1142,9 +1143,9 @@ static bool notify2_unpack_msg( SPOOLSS_NOTIFY_MSG *msg, struct timeval *tv, voi DEBUG(3, ("notify2_unpack_msg: value1 = %d, value2 = %d\n", msg->notify.value[0], msg->notify.value[1])); else - dump_data(3, (uint8 *)msg->notify.data, msg->len); + dump_data(3, (uint8_t *)msg->notify.data, msg->len); - return True; + return true; } /******************************************************************** @@ -1233,7 +1234,8 @@ static void receive_notify2_message_list(struct messaging_context *msg, /* cleanup */ - DEBUG(10,("receive_notify2_message_list: processed %u messages\n", (uint32)msg_count )); + DEBUG(10,("receive_notify2_message_list: processed %u messages\n", + (uint32_t)msg_count )); notify_msg_ctr_destroy( &messages ); @@ -1246,21 +1248,21 @@ static void receive_notify2_message_list(struct messaging_context *msg, driver ********************************************************************/ -static bool srv_spoolss_drv_upgrade_printer(char* drivername) +static bool srv_spoolss_drv_upgrade_printer(const char *drivername) { int len = strlen(drivername); if (!len) - return False; + return false; DEBUG(10,("srv_spoolss_drv_upgrade_printer: Sending message about driver upgrade [%s]\n", drivername)); messaging_send_buf(smbd_messaging_context(), procid_self(), MSG_PRINTER_DRVUPGRADE, - (uint8 *)drivername, len+1); + (uint8_t *)drivername, len+1); - return True; + return true; } /********************************************************************** @@ -1328,7 +1330,7 @@ void update_monitored_printq_cache( void ) int snum; /* loop through all printers and update the cache where - client_connected == True */ + client_connected == true */ while ( printer ) { if ( (printer->printer_type == SPLHND_PRINTER) @@ -1354,16 +1356,16 @@ static bool srv_spoolss_reset_printerdata(char* drivername) int len = strlen(drivername); if (!len) - return False; + return false; DEBUG(10,("srv_spoolss_reset_printerdata: Sending message about resetting printerdata [%s]\n", drivername)); messaging_send_buf(smbd_messaging_context(), procid_self(), MSG_PRINTERDATA_INIT_RESET, - (uint8 *)drivername, len+1); + (uint8_t *)drivername, len+1); - return True; + return true; } /********************************************************************** @@ -1527,7 +1529,7 @@ bool convert_devicemode(const char *printername, if ((devmode->__driverextra_length != 0) && (devmode->driverextra_data.data != NULL)) { SAFE_FREE(nt_devmode->nt_dev_private); nt_devmode->driverextra = devmode->__driverextra_length; - if((nt_devmode->nt_dev_private=SMB_MALLOC_ARRAY(uint8, nt_devmode->driverextra)) == NULL) + if((nt_devmode->nt_dev_private = SMB_MALLOC_ARRAY(uint8_t, nt_devmode->driverextra)) == NULL) return false; memcpy(nt_devmode->nt_dev_private, devmode->driverextra_data.data, nt_devmode->driverextra); } @@ -1544,20 +1546,19 @@ bool convert_devicemode(const char *printername, WERROR _spoolss_OpenPrinterEx(pipes_struct *p, struct spoolss_OpenPrinterEx *r) { - char *name = CONST_DISCARD(char *, r->in.printername); int snum; Printer_entry *Printer=NULL; - if (!name) { + if (!r->in.printername) { return WERR_INVALID_PARAM; } /* some sanity check because you can open a printer or a print server */ /* aka: \\server\printer or \\server */ - DEBUGADD(3,("checking name: %s\n",name)); + DEBUGADD(3,("checking name: %s\n", r->in.printername)); - if (!open_printer_hnd(p, r->out.handle, name, 0)) { + if (!open_printer_hnd(p, r->out.handle, r->in.printername, 0)) { ZERO_STRUCTP(r->out.handle); return WERR_INVALID_PARAM; } @@ -1565,7 +1566,7 @@ WERROR _spoolss_OpenPrinterEx(pipes_struct *p, Printer = find_printer_index_by_hnd(p, r->out.handle); if ( !Printer ) { DEBUG(0,("_spoolss_OpenPrinterEx: logic error. Can't find printer " - "handle we created for printer %s\n", name )); + "handle we created for printer %s\n", r->in.printername)); close_printer_handle(p, r->out.handle); ZERO_STRUCTP(r->out.handle); return WERR_INVALID_PARAM; @@ -2017,7 +2018,7 @@ static WERROR _spoolss_enddocprinter_internal(pipes_struct *p, if (!get_printer_snum(p, handle, &snum, NULL)) return WERR_BADFID; - Printer->document_started=False; + Printer->document_started = false; print_job_end(snum, Printer->jobid,NORMAL_CLOSE); /* error codes unhandled so far ... */ @@ -2064,7 +2065,7 @@ WERROR _spoolss_DeletePrinter(pipes_struct *p, result = delete_printer_handle(p, r->in.handle); - update_c_setprinter(False); + update_c_setprinter(false); return result; } @@ -2074,7 +2075,7 @@ WERROR _spoolss_DeletePrinter(pipes_struct *p, * long architecture string ******************************************************************/ -static int get_version_id (char * arch) +static int get_version_id(const char *arch) { int i; struct table_node archi_table[]= { @@ -2105,8 +2106,6 @@ static int get_version_id (char * arch) WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, struct spoolss_DeletePrinterDriver *r) { - char *driver; - char *arch; NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; @@ -2127,24 +2126,26 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, return WERR_ACCESS_DENIED; } - driver = CONST_DISCARD(char *, r->in.driver); - arch = CONST_DISCARD(char *, r->in.architecture); - /* check that we have a valid driver name first */ - if ((version=get_version_id(arch)) == -1) + if ((version = get_version_id(r->in.architecture)) == -1) return WERR_INVALID_ENVIRONMENT; ZERO_STRUCT(info); ZERO_STRUCT(info_win2k); - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, r->in.driver, + r->in.architecture, + version))) { /* try for Win2k driver if "Windows NT x86" */ if ( version == 2 ) { version = 3; - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, + r->in.driver, + r->in.architecture, + version))) { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } @@ -2164,13 +2165,15 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, if ( version == 2 ) { - if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) + if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, + r->in.driver, + r->in.architecture, 3))) { /* if we get to here, we now have 2 driver info structures to remove */ /* remove the Win2k driver first*/ status_win2k = delete_printer_driver( - p, info_win2k.info_3, 3, False ); + p, info_win2k.info_3, 3, false); free_a_printer_driver( info_win2k, 3 ); /* this should not have failed---if it did, report to client */ @@ -2182,7 +2185,7 @@ WERROR _spoolss_DeletePrinterDriver(pipes_struct *p, } } - status = delete_printer_driver(p, info.info_3, version, False); + status = delete_printer_driver(p, info.info_3, version, false); /* if at least one of the deletes succeeded return OK */ @@ -2202,12 +2205,9 @@ done: WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, struct spoolss_DeletePrinterDriverEx *r) { - char *driver; - char *arch; NT_PRINTER_DRIVER_INFO_LEVEL info; NT_PRINTER_DRIVER_INFO_LEVEL info_win2k; int version; - uint32_t flags = r->in.delete_flags; bool delete_files; WERROR status; WERROR status_win2k = WERR_ACCESS_DENIED; @@ -2225,22 +2225,20 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, return WERR_ACCESS_DENIED; } - driver = CONST_DISCARD(char *, r->in.driver); - arch = CONST_DISCARD(char *, r->in.architecture); - /* check that we have a valid driver name first */ - if ((version=get_version_id(arch)) == -1) { + if ((version = get_version_id(r->in.architecture)) == -1) { /* this is what NT returns */ return WERR_INVALID_ENVIRONMENT; } - if ( flags & DPD_DELETE_SPECIFIC_VERSION ) + if (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) version = r->in.version; ZERO_STRUCT(info); ZERO_STRUCT(info_win2k); - status = get_a_printer_driver(&info, 3, driver, arch, version); + status = get_a_printer_driver(&info, 3, r->in.driver, + r->in.architecture, version); if ( !W_ERROR_IS_OK(status) ) { @@ -2250,13 +2248,15 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, * then we've failed */ - if ( (flags&DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) + if ( (r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) || (version !=2) ) goto done; /* try for Win2k driver if "Windows NT x86" */ version = 3; - if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, driver, arch, version))) { + if (!W_ERROR_IS_OK(get_a_printer_driver(&info, 3, r->in.driver, + r->in.architecture, + version))) { status = WERR_UNKNOWN_PRINTER_DRIVER; goto done; } @@ -2279,11 +2279,11 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, * Refer to MSDN docs on DeletePrinterDriverEx() for details. */ - delete_files = flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); + delete_files = r->in.delete_flags & (DPD_DELETE_ALL_FILES|DPD_DELETE_UNUSED_FILES); /* fail if any files are in use and DPD_DELETE_ALL_FILES is set */ - if ( delete_files && printer_driver_files_in_use(info.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { + if ( delete_files && printer_driver_files_in_use(info.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) { /* no idea of the correct error here */ status = WERR_ACCESS_DENIED; goto done; @@ -2292,11 +2292,13 @@ WERROR _spoolss_DeletePrinterDriverEx(pipes_struct *p, /* also check for W32X86/3 if necessary; maybe we already have? */ - if ( (version == 2) && ((flags&DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { - if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, driver, arch, 3))) + if ( (version == 2) && ((r->in.delete_flags & DPD_DELETE_SPECIFIC_VERSION) != DPD_DELETE_SPECIFIC_VERSION) ) { + if (W_ERROR_IS_OK(get_a_printer_driver(&info_win2k, 3, + r->in.driver, + r->in.architecture, 3))) { - if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (flags&DPD_DELETE_ALL_FILES) ) { + if ( delete_files && printer_driver_files_in_use(info_win2k.info_3) & (r->in.delete_flags & DPD_DELETE_ALL_FILES) ) { /* no idea of the correct error here */ free_a_printer_driver( info_win2k, 3 ); status = WERR_ACCESS_DENIED; @@ -2341,8 +2343,9 @@ static WERROR delete_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char Internal routine for storing printerdata ***************************************************************************/ -WERROR set_printer_dataex( NT_PRINTER_INFO_LEVEL *printer, const char *key, const char *value, - uint32 type, uint8 *data, int real_len ) +WERROR set_printer_dataex(NT_PRINTER_INFO_LEVEL *printer, + const char *key, const char *value, + uint32_t type, uint8_t *data, int real_len) { /* the registry objects enforce uniqueness based on value name */ @@ -2409,10 +2412,10 @@ static WERROR getprinterdata_printer_server(TALLOC_CTX *mem_ctx, } /* REG_BINARY - * uint32 size = 0x114 - * uint32 major = 5 - * uint32 minor = [0|1] - * uint32 build = [2195|2600] + * uint32_t size = 0x114 + * uint32_t major = 5 + * uint32_t minor = [0|1] + * uint32_t build = [2195|2600] * extra unicode string = e.g. "Service Pack 3" */ if (!StrCaseCmp(value, "OSVersion")) { @@ -2596,12 +2599,12 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, if ( is_zero_addr((struct sockaddr *)client_ss) ) { if ( !resolve_name( remote_machine, &rm_addr, 0x20) ) { DEBUG(2,("spoolss_connect_to_client: Can't resolve address for %s\n", remote_machine)); - return False; + return false; } if (ismyaddr((struct sockaddr *)&rm_addr)) { DEBUG(0,("spoolss_connect_to_client: Machine %s is one of our addresses. Cannot add to ourselves.\n", remote_machine)); - return False; + return false; } } else { char addr[INET6_ADDRSTRLEN]; @@ -2623,13 +2626,13 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, if ( !NT_STATUS_IS_OK( ret ) ) { DEBUG(2,("spoolss_connect_to_client: connection to [%s] failed!\n", remote_machine )); - return False; + return false; } if ( the_cli->protocol != PROTOCOL_NT1 ) { DEBUG(0,("spoolss_connect_to_client: machine %s didn't negotiate NT protocol.\n", remote_machine)); cli_shutdown(the_cli); - return False; + return false; } /* @@ -2642,10 +2645,10 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, DEBUG(2,("spoolss_connect_to_client: unable to open the spoolss pipe on machine %s. Error was : %s.\n", remote_machine, nt_errstr(ret))); cli_shutdown(the_cli); - return False; + return false; } - return True; + return true; } /*************************************************************************** @@ -2653,7 +2656,7 @@ static bool spoolss_connect_to_client(struct rpc_pipe_client **pp_pipe, ****************************************************************************/ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, - uint32 localprinter, uint32 type, + uint32_t localprinter, uint32_t type, struct policy_handle *handle, struct sockaddr_storage *client_ss) { @@ -2670,14 +2673,14 @@ static bool srv_spoolss_replyopenprinter(int snum, const char *printer, fstrcpy(unix_printer, printer+2); /* the +2 is to strip the leading 2 backslashs */ if ( !spoolss_connect_to_client( ¬ify_cli_pipe, client_ss, unix_printer )) - return False; + return false; messaging_register(smbd_messaging_context(), NULL, MSG_PRINTER_NOTIFY2, receive_notify2_message_list); /* Tell the connections db we're now interested in printer * notify messages. */ - register_message_flags( True, FLAG_MSG_PRINT_NOTIFY ); + register_message_flags(true, FLAG_MSG_PRINT_NOTIFY); } /* @@ -2811,7 +2814,7 @@ WERROR _spoolss_RemoteFindFirstPrinterChangeNotifyEx(pipes_struct *p, &Printer->notify.client_hnd, &client_ss)) return WERR_SERVER_UNAVAILABLE; - Printer->notify.client_connected=True; + Printer->notify.client_connected = true; return WERR_OK; } @@ -3296,7 +3299,7 @@ struct s_notify_info_data_table /* A table describing the various print notification constants and whether the notification data is a pointer to a variable sized - buffer, a one value uint32 or a two value uint32. */ + buffer, a one value uint32_t or a two value uint32_t. */ static const struct s_notify_info_data_table notify_info_data_table[] = { @@ -3386,11 +3389,11 @@ static bool search_notify(enum spoolss_NotifyType type, notify_info_data_table[i].field == field && notify_info_data_table[i].fn != NULL) { *value = i; - return True; + return true; } } - return False; + return false; } /**************************************************************************** @@ -3435,7 +3438,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, option_type->count, lp_servicename(snum))); if (!W_ERROR_IS_OK(get_a_printer(print_hnd, &printer, 2, lp_const_servicename(snum)))) - return False; + return false; for(field_num=0; field_num < option_type->count; field_num++) { field = option_type->fields[field_num].field; @@ -3451,7 +3454,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, if (info->notifies == NULL) { DEBUG(2,("construct_notify_printer_info: failed to enlarge buffer info->data!\n")); free_a_printer(&printer, 2); - return False; + return false; } current_data = &info->notifies[info->count]; @@ -3468,7 +3471,7 @@ static bool construct_notify_printer_info(Printer_entry *print_hnd, } free_a_printer(&printer, 2); - return True; + return true; } /******************************************************************* @@ -3509,7 +3512,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, info->count + 1); if (info->notifies == NULL) { DEBUG(2,("construct_notify_jobs_info: failed to enlarg buffer info->data!\n")); - return False; + return false; } current_data=&(info->notifies[info->count]); @@ -3520,7 +3523,7 @@ static bool construct_notify_jobs_info(print_queue_struct *queue, info->count++; } - return True; + return true; } /* @@ -3627,7 +3630,7 @@ static WERROR printer_notify_info(pipes_struct *p, struct policy_handle *hnd, int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, hnd); int i; - uint32 id; + uint32_t id; struct spoolss_NotifyOption *option; struct spoolss_NotifyOptionType option_type; int count,j; @@ -3747,7 +3750,7 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, /* We need to keep track of the change value to send back in RRPCN replies otherwise our updates are ignored. */ - Printer->notify.fnpcn = True; + Printer->notify.fnpcn = true; if (Printer->notify.client_connected) { DEBUG(10,("_spoolss_RouterRefreshPrinterChangeNotify: " @@ -3770,7 +3773,7 @@ WERROR _spoolss_RouterRefreshPrinterChangeNotify(pipes_struct *p, break; } - Printer->notify.fnpcn = False; + Printer->notify.fnpcn = false; done: return result; @@ -4201,61 +4204,88 @@ static bool snum_is_shared_printer(int snum) Spoolss_enumprinters. ********************************************************************/ -static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx, - uint32_t flags, - union spoolss_PrinterInfo **info_p, - uint32_t *count) +static WERROR enum_all_printers_info_level(TALLOC_CTX *mem_ctx, + uint32_t level, + uint32_t flags, + union spoolss_PrinterInfo **info_p, + uint32_t *count_p) { int snum; int n_services = lp_numservices(); union spoolss_PrinterInfo *info = NULL; + uint32_t count = 0; WERROR result = WERR_OK; - DEBUG(4,("enum_all_printers_info_1\n")); - - *count = 0; + *count_p = 0; + *info_p = NULL; - for (snum=0; snum<n_services; snum++) { + for (snum = 0; snum < n_services; snum++) { NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - struct spoolss_PrinterInfo1 info1; if (!snum_is_shared_printer(snum)) { continue; } - DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); + DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", + lp_servicename(snum), snum)); - result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(result)) { - continue; + info = TALLOC_REALLOC_ARRAY(mem_ctx, info, + union spoolss_PrinterInfo, + count + 1); + if (!info) { + result = WERR_NOMEM; + goto out; } - result = construct_printer_info1(info, ntprinter, flags, &info1, snum); - free_a_printer(&ntprinter,2); + result = get_a_printer(NULL, &ntprinter, 2, + lp_const_servicename(snum)); if (!W_ERROR_IS_OK(result)) { - continue; + goto out; } - info = TALLOC_REALLOC_ARRAY(mem_ctx, info, - union spoolss_PrinterInfo, - *count + 1); - if (!info) { - DEBUG(2,("enum_all_printers_info_1: failed to enlarge printers buffer!\n")); - result = WERR_NOMEM; + switch (level) { + case 0: + result = construct_printer_info0(info, ntprinter, + &info[count].info0, snum); + break; + case 1: + result = construct_printer_info1(info, ntprinter, flags, + &info[count].info1, snum); + break; + case 2: + result = construct_printer_info2(info, ntprinter, + &info[count].info2, snum); + break; + case 4: + result = construct_printer_info4(info, ntprinter, + &info[count].info4, snum); + break; + case 5: + result = construct_printer_info5(info, ntprinter, + &info[count].info5, snum); + break; + + default: + result = WERR_UNKNOWN_LEVEL; + free_a_printer(&ntprinter, 2); goto out; } - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_1\n", *count)); + free_a_printer(&ntprinter, 2); + if (!W_ERROR_IS_OK(result)) { + goto out; + } - info[*count].info1 = info1; - (*count)++; + count++; } + *count_p = count; + *info_p = info; + out: if (!W_ERROR_IS_OK(result)) { TALLOC_FREE(info); - *count = 0; return result; } @@ -4265,6 +4295,35 @@ static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx, } /******************************************************************** + * handle enumeration of printers at level 0 + ********************************************************************/ + +static WERROR enumprinters_level0(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *servername, + union spoolss_PrinterInfo **info, + uint32_t *count) +{ + DEBUG(4,("enum_all_printers_info_0\n")); + + return enum_all_printers_info_level(mem_ctx, 0, flags, info, count); +} + + +/******************************************************************** +********************************************************************/ + +static WERROR enum_all_printers_info_1(TALLOC_CTX *mem_ctx, + uint32_t flags, + union spoolss_PrinterInfo **info, + uint32_t *count) +{ + DEBUG(4,("enum_all_printers_info_1\n")); + + return enum_all_printers_info_level(mem_ctx, 1, flags, info, count); +} + +/******************************************************************** enum_all_printers_info_1_local. *********************************************************************/ @@ -4340,64 +4399,12 @@ static WERROR enum_all_printers_info_1_network(TALLOC_CTX *mem_ctx, ********************************************************************/ static WERROR enum_all_printers_info_2(TALLOC_CTX *mem_ctx, - union spoolss_PrinterInfo **info_p, + union spoolss_PrinterInfo **info, uint32_t *count) { - int snum; - int n_services = lp_numservices(); - union spoolss_PrinterInfo *info = NULL; - WERROR result = WERR_OK; - - *count = 0; - - for (snum=0; snum<n_services; snum++) { - - struct spoolss_PrinterInfo2 info2; - NT_PRINTER_INFO_LEVEL *ntprinter = NULL; - - if (!snum_is_shared_printer(snum)) { - continue; - } - - DEBUG(4,("Found a printer in smb.conf: %s[%x]\n", lp_servicename(snum), snum)); - - result = get_a_printer(NULL, &ntprinter, 2, lp_const_servicename(snum)); - if (!W_ERROR_IS_OK(result)) { - continue; - } - - result = construct_printer_info2(info, ntprinter, &info2, snum); - free_a_printer(&ntprinter, 2); - if (!W_ERROR_IS_OK(result)) { - continue; - } - - info = TALLOC_REALLOC_ARRAY(mem_ctx, info, - union spoolss_PrinterInfo, - *count + 1); - if (!info) { - DEBUG(2,("enum_all_printers_info_2: failed to enlarge printers buffer!\n")); - result = WERR_NOMEM; - goto out; - } - - DEBUG(4,("ReAlloced memory for [%d] PRINTER_INFO_2\n", *count + 1)); + DEBUG(4,("enum_all_printers_info_2\n")); - info[*count].info2 = info2; - - (*count)++; - } - - out: - if (!W_ERROR_IS_OK(result)) { - TALLOC_FREE(info); - *count = 0; - return result; - } - - *info_p = info; - - return WERR_OK; + return enum_all_printers_info_level(mem_ctx, 2, 0, info, count); } /******************************************************************** @@ -4457,6 +4464,22 @@ static WERROR enumprinters_level2(TALLOC_CTX *mem_ctx, } /******************************************************************** + * handle enumeration of printers at level 4 + ********************************************************************/ + +static WERROR enumprinters_level4(TALLOC_CTX *mem_ctx, + uint32_t flags, + const char *servername, + union spoolss_PrinterInfo **info, + uint32_t *count) +{ + DEBUG(4,("enum_all_printers_info_4\n")); + + return enum_all_printers_info_level(mem_ctx, 4, flags, info, count); +} + + +/******************************************************************** * handle enumeration of printers at level 5 ********************************************************************/ @@ -4466,8 +4489,9 @@ static WERROR enumprinters_level5(TALLOC_CTX *mem_ctx, union spoolss_PrinterInfo **info, uint32_t *count) { -/* return enum_all_printers_info_5(mem_ctx, info, offered, needed, count);*/ - return WERR_OK; + DEBUG(4,("enum_all_printers_info_5\n")); + + return enum_all_printers_info_level(mem_ctx, 5, flags, info, count); } /**************************************************************** @@ -4509,6 +4533,10 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p, W_ERROR_HAVE_NO_MEMORY(name); switch (r->in.level) { + case 0: + result = enumprinters_level0(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 1: result = enumprinters_level1(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); @@ -4517,14 +4545,14 @@ WERROR _spoolss_EnumPrinters(pipes_struct *p, result = enumprinters_level2(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); break; + case 4: + result = enumprinters_level4(p->mem_ctx, r->in.flags, name, + r->out.info, r->out.count); + break; case 5: result = enumprinters_level5(p->mem_ctx, r->in.flags, name, r->out.info, r->out.count); break; - case 3: - case 4: - result = WERR_OK; /* ??? */ - break; default: return WERR_UNKNOWN_LEVEL; } @@ -5157,7 +5185,7 @@ WERROR _spoolss_StartPagePrinter(pipes_struct *p, return WERR_BADFID; } - Printer->page_started=True; + Printer->page_started = true; return WERR_OK; } @@ -5181,7 +5209,7 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p, if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; - Printer->page_started=False; + Printer->page_started = false; print_job_endpage(snum, Printer->jobid); return WERR_OK; @@ -5194,7 +5222,6 @@ WERROR _spoolss_EndPagePrinter(pipes_struct *p, WERROR _spoolss_StartDocPrinter(pipes_struct *p, struct spoolss_StartDocPrinter *r) { - uint32_t *jobid = r->out.job_id; struct spoolss_DocumentInfo1 *info_1; int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); @@ -5222,7 +5249,7 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, if (info_1->datatype) { if (strcmp(info_1->datatype, "RAW") != 0) { - (*jobid)=0; + *r->out.job_id = 0; return WERR_INVALID_DATATYPE; } } @@ -5243,8 +5270,8 @@ WERROR _spoolss_StartDocPrinter(pipes_struct *p, return map_werror_from_unix(errno); } - Printer->document_started=True; - (*jobid) = Printer->jobid; + Printer->document_started = true; + *r->out.job_id = Printer->jobid; return WERR_OK; } @@ -5266,9 +5293,7 @@ WERROR _spoolss_EndDocPrinter(pipes_struct *p, WERROR _spoolss_WritePrinter(pipes_struct *p, struct spoolss_WritePrinter *r) { - uint32 buffer_size = r->in._data_size; - uint8 *buffer = r->in.data.data; - uint32 *buffer_written = &r->in._data_size; + uint32_t buffer_written; int snum; Printer_entry *Printer = find_printer_index_by_hnd(p, r->in.handle); @@ -5282,9 +5307,11 @@ WERROR _spoolss_WritePrinter(pipes_struct *p, if (!get_printer_snum(p, r->in.handle, &snum, NULL)) return WERR_BADFID; - (*buffer_written) = (uint32)print_job_write(snum, Printer->jobid, (const char *)buffer, - (SMB_OFF_T)-1, (size_t)buffer_size); - if (*buffer_written == (uint32)-1) { + buffer_written = (uint32_t)print_job_write(snum, Printer->jobid, + (const char *)r->in.data.data, + (SMB_OFF_T)-1, + (size_t)r->in._data_size); + if (buffer_written == (uint32_t)-1) { *r->out.num_written = 0; if (errno == ENOSPC) return WERR_NO_SPOOL_SPACE; @@ -5515,7 +5542,7 @@ static bool check_printer_ok(NT_PRINTER_INFO_LEVEL_2 *info, int snum) - return True; + return true; } /**************************************************************************** @@ -5527,7 +5554,7 @@ WERROR add_port_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, const char *portname char *command = NULL; int ret; SE_PRIV se_printop = SE_PRINT_OPERATOR; - bool is_print_op = False; + bool is_print_op = false; if ( !*cmd ) { return WERR_ACCESS_DENIED; @@ -5579,7 +5606,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV int ret; int fd; SE_PRIV se_printop = SE_PRINT_OPERATOR; - bool is_print_op = False; + bool is_print_op = false; char *remote_machine = talloc_strdup(ctx, "%m"); if (!remote_machine) { @@ -5631,11 +5658,11 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV if ( ret != 0 ) { if (fd != -1) close(fd); - return False; + return false; } /* reload our services immediately */ - reload_services( False ); + reload_services(false); numlines = 0; /* Get lines and convert them back to dos-codepage */ @@ -5653,7 +5680,7 @@ bool add_printer_hook(TALLOC_CTX *ctx, NT_USER_TOKEN *token, NT_PRINTER_INFO_LEV } TALLOC_FREE(qlines); - return True; + return true; } @@ -5782,7 +5809,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->comment, old_printer->info_2->comment)) { init_unistr2( &buffer, printer->info_2->comment, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "description", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_comment(snum, printer->info_2->comment); } @@ -5790,7 +5817,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->sharename, old_printer->info_2->sharename)) { init_unistr2( &buffer, printer->info_2->sharename, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shareName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_sharename(snum, printer->info_2->sharename); } @@ -5806,7 +5833,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, init_unistr2( &buffer, pname, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "printerName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_printername( snum, pname ); } @@ -5814,7 +5841,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->portname, old_printer->info_2->portname)) { init_unistr2( &buffer, printer->info_2->portname, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "portName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_port(snum, printer->info_2->portname); } @@ -5822,7 +5849,7 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, if (!strequal(printer->info_2->location, old_printer->info_2->location)) { init_unistr2( &buffer, printer->info_2->location, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "location", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); notify_printer_location(snum, printer->info_2->location); } @@ -5832,15 +5859,15 @@ static WERROR update_printer(pipes_struct *p, struct policy_handle *handle, init_unistr2( &buffer, global_myname(), UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "serverName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "shortServerName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); slprintf( asc_buffer, sizeof(asc_buffer)-1, "\\\\%s\\%s", global_myname(), printer->info_2->sharename ); init_unistr2( &buffer, asc_buffer, UNI_STR_TERMINATE); set_printer_dataex( printer, SPOOL_DSSPOOLER_KEY, "uNCName", - REG_SZ, (uint8*)buffer.buffer, buffer.uni_str_len*2 ); + REG_SZ, (uint8_t *)buffer.buffer, buffer.uni_str_len*2 ); /* Update printer info */ result = mod_a_printer(printer, 2); @@ -5942,7 +5969,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, return WERR_BADFID; } - if (Printer->notify.client_connected==True) { + if (Printer->notify.client_connected == true) { int snum = -1; if ( Printer->printer_type == SPLHND_SERVER) @@ -5959,7 +5986,7 @@ WERROR _spoolss_FindClosePrinterNotify(pipes_struct *p, Printer->notify.localmachine[0]='\0'; Printer->notify.printerlocal=0; TALLOC_FREE(Printer->notify.option); - Printer->notify.client_connected=False; + Printer->notify.client_connected = false; return WERR_OK; } @@ -6275,9 +6302,6 @@ WERROR _spoolss_ScheduleJob(pipes_struct *p, WERROR _spoolss_SetJob(pipes_struct *p, struct spoolss_SetJob *r) { - uint32 jobid = r->in.job_id; - uint32 command = r->in.command; - int snum; WERROR errcode = WERR_BADFUNC; @@ -6285,25 +6309,25 @@ WERROR _spoolss_SetJob(pipes_struct *p, return WERR_BADFID; } - if (!print_job_exists(lp_const_servicename(snum), jobid)) { + if (!print_job_exists(lp_const_servicename(snum), r->in.job_id)) { return WERR_INVALID_PRINTER_NAME; } - switch (command) { + switch (r->in.command) { case SPOOLSS_JOB_CONTROL_CANCEL: case SPOOLSS_JOB_CONTROL_DELETE: - if (print_job_delete(p->server_info, snum, jobid, &errcode)) { + if (print_job_delete(p->server_info, snum, r->in.job_id, &errcode)) { errcode = WERR_OK; } break; case SPOOLSS_JOB_CONTROL_PAUSE: - if (print_job_pause(p->server_info, snum, jobid, &errcode)) { + if (print_job_pause(p->server_info, snum, r->in.job_id, &errcode)) { errcode = WERR_OK; } break; case SPOOLSS_JOB_CONTROL_RESTART: case SPOOLSS_JOB_CONTROL_RESUME: - if (print_job_resume(p->server_info, snum, jobid, &errcode)) { + if (print_job_resume(p->server_info, snum, r->in.job_id, &errcode)) { errcode = WERR_OK; } break; @@ -7209,7 +7233,7 @@ static WERROR spoolss_addprinterex_level_2(pipes_struct *p, return WERR_ACCESS_DENIED; } - update_c_setprinter(False); + update_c_setprinter(false); free_a_printer(&printer,2); return WERR_OK; @@ -7250,8 +7274,8 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p, struct spoolss_AddDriverInfoCtr *info = r->in.info_ctr; WERROR err = WERR_OK; NT_PRINTER_DRIVER_INFO_LEVEL driver; - fstring driver_name; - uint32 version; + const char *driver_name = NULL; + uint32_t version; const char *fn; switch (p->hdr_req.opnum) { @@ -7300,12 +7324,10 @@ WERROR _spoolss_AddPrinterDriver(pipes_struct *p, switch(level) { case 3: - fstrcpy(driver_name, - driver.info_3->name ? driver.info_3->name : ""); + driver_name = driver.info_3->name ? driver.info_3->name : ""; break; case 6: - fstrcpy(driver_name, - driver.info_6->name ? driver.info_6->name : ""); + driver_name = driver.info_6->name ? driver.info_6->name : ""; break; } diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c index cd04462426..c9c457b364 100644 --- a/source3/rpcclient/cmd_spoolss.c +++ b/source3/rpcclient/cmd_spoolss.c @@ -257,9 +257,10 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli, union spoolss_PrinterInfo *info; uint32_t i, count; const char *name; + uint32_t flags = PRINTER_ENUM_LOCAL; - if (argc > 3) { - printf("Usage: %s [level] [name]\n", argv[0]); + if (argc > 4) { + printf("Usage: %s [level] [name] [flags]\n", argv[0]); return WERR_OK; } @@ -267,14 +268,18 @@ static WERROR cmd_spoolss_enum_printers(struct rpc_pipe_client *cli, level = atoi(argv[1]); } - if (argc == 3) { + if (argc >= 3) { name = argv[2]; } else { name = cli->srv_name_slash; } + if (argc == 4) { + flags = atoi(argv[3]); + } + result = rpccli_spoolss_enumprinters(cli, mem_ctx, - PRINTER_ENUM_LOCAL, + flags, name, level, 0, @@ -417,7 +422,7 @@ static WERROR cmd_spoolss_setprinter(struct rpc_pipe_client *cli, struct policy_handle pol; WERROR result; NTSTATUS status; - uint32 info_level = 2; + uint32_t info_level = 2; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; const char *printername, *comment = NULL; @@ -493,7 +498,7 @@ static WERROR cmd_spoolss_setprintername(struct rpc_pipe_client *cli, struct policy_handle pol; WERROR result; NTSTATUS status; - uint32 info_level = 2; + uint32_t info_level = 2; union spoolss_PrinterInfo info; const char *printername, *new_printername = NULL; @@ -644,7 +649,7 @@ static void display_reg_value(REGISTRY_VALUE value) switch(value.type) { case REG_DWORD: printf("%s: REG_DWORD: 0x%08x\n", value.valuename, - *((uint32 *) value.data_p)); + *((uint32_t *) value.data_p)); break; case REG_SZ: rpcstr_pull_talloc(talloc_tos(), @@ -673,7 +678,7 @@ static void display_reg_value(REGISTRY_VALUE value) break; } case REG_MULTI_SZ: { - uint32 i, num_values; + uint32_t i, num_values; char **values; if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, @@ -1338,7 +1343,7 @@ static WERROR cmd_spoolss_addprinterdriver(struct rpc_pipe_client *cli, { WERROR result; NTSTATUS status; - uint32 level = 3; + uint32_t level = 3; struct spoolss_AddDriverInfoCtr info_ctr; struct spoolss_AddDriverInfo3 info3; const char *arch; @@ -1467,7 +1472,7 @@ static WERROR cmd_spoolss_setdriver(struct rpc_pipe_client *cli, struct policy_handle pol; WERROR result; NTSTATUS status; - uint32 level = 2; + uint32_t level = 2; const char *printername; union spoolss_PrinterInfo info; struct spoolss_SetPrinterInfoCtr info_ctr; @@ -2051,7 +2056,7 @@ static WERROR cmd_spoolss_enum_forms(struct rpc_pipe_client *cli, struct policy_handle handle; WERROR werror; const char *printername; - uint32 num_forms, level = 1, i; + uint32_t num_forms, level = 1, i; union spoolss_FormInfo *forms; /* Parse the command arguments */ @@ -2544,7 +2549,7 @@ static WERROR cmd_spoolss_enum_data_ex( struct rpc_pipe_client *cli, const char **argv) { WERROR result; - uint32 i; + uint32_t i; const char *printername; struct policy_handle hnd; uint32_t count; @@ -2764,7 +2769,7 @@ static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); - return False; + return false; } printf("ok\n"); @@ -2777,13 +2782,13 @@ static bool compare_printer( struct rpc_pipe_client *cli1, struct policy_handle if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); talloc_destroy(mem_ctx); - return False; + return false; } printf("ok\n"); talloc_destroy(mem_ctx); - return True; + return true; } /**************************************************************************** @@ -2796,7 +2801,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy WERROR werror; TALLOC_CTX *mem_ctx = talloc_init("compare_printer_secdesc"); SEC_DESC *sd1, *sd2; - bool result = True; + bool result = true; printf("Retrieving printer security for %s...", cli1->desthost); @@ -2807,7 +2812,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy &info1); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); - result = False; + result = false; goto done; } printf("ok\n"); @@ -2820,7 +2825,7 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy &info2); if ( !W_ERROR_IS_OK(werror) ) { printf("failed (%s)\n", win_errstr(werror)); - result = False; + result = false; goto done; } printf("ok\n"); @@ -2833,13 +2838,13 @@ static bool compare_printer_secdesc( struct rpc_pipe_client *cli1, struct policy if ( (sd1 != sd2) && ( !sd1 || !sd2 ) ) { printf("NULL secdesc!\n"); - result = False; + result = false; goto done; } if (!sec_desc_equal( sd1, sd2 ) ) { printf("Security Descriptors *not* equal!\n"); - result = False; + result = false; goto done; } diff --git a/source3/samba4.m4 b/source3/samba4.m4 index b5c7c74689..568283cd87 100644 --- a/source3/samba4.m4 +++ b/source3/samba4.m4 @@ -69,14 +69,14 @@ AC_CONFIG_FILES(../source4/librpc/dcerpc_atsvc.pc) m4_include(../source4/min_versions.m4) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTALLOC, talloc >= TALLOC_MIN_VERSION, [], [ SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= TDB_MIN_VERSION, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -86,13 +86,13 @@ SMB_EXT_LIB_FROM_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, SMB_INCLUDE_MK(../lib/tdb/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = $TEVENT_REQUIRED_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBTEVENT, tevent = TEVENT_REQUIRED_VERSION, [],[m4_include(../lib/tevent/samba.m4)] ) SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION, +SMB_EXT_LIB_FROM_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) diff --git a/source3/samba4.mk b/source3/samba4.mk index 7e7690aadf..3f661bdd14 100644 --- a/source3/samba4.mk +++ b/source3/samba4.mk @@ -225,32 +225,32 @@ test4-%:: valgrindtest4:: valgrindtest-all valgrindtest4-quick:: all - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_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)" \ + SAMBA_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)" \ + SAMBA_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)" \ + SAMBA_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)" \ + SAMBA_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)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST4) $(SELFTEST4_NOSLOW_OPTS) --socket-wrapper --testenv plugins: $(PLUGINS) diff --git a/source3/selftest/tests.sh b/source3/selftest/tests.sh index f88dab0337..ea59f0ee8e 100755 --- a/source3/selftest/tests.sh +++ b/source3/selftest/tests.sh @@ -120,6 +120,10 @@ plantest "blackbox.smbclient_s3.plain" dc BINDIR="$BINDIR" script/tests/test_smb plantest "blackbox.smbclient_s3.plain member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD plantest "blackbox.smbclient_s3.plain domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD +# sign, only the member server allows signing +plantest "blackbox.smbclient_s3.sign member creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$SERVER\\\\\$USERNAME \$PASSWORD "--signing=required" +plantest "blackbox.smbclient_s3.sign domain creds" member BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$DOMAIN\\\\\$DC_USERNAME \$DC_PASSWORD "--signing=required" + # encrypted plantest "blackbox.smbclient_s3.crypt" dc BINDIR="$BINDIR" script/tests/test_smbclient_s3.sh \$SERVER \$SERVER_IP \$USERNAME \$PASSWORD "-e" diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c index cfa4b430eb..77616be48c 100644 --- a/source3/smbd/aio.c +++ b/source3/smbd/aio.c @@ -197,7 +197,6 @@ bool schedule_aio_read_and_X(connection_struct *conn, fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt, (unsigned int)aio_ex->req->mid )); - srv_defer_sign_response(aio_ex->req->mid); outstanding_aio_calls++; return True; } @@ -303,6 +302,7 @@ bool schedule_aio_write_and_X(connection_struct *conn, SSVAL(aio_ex->outbuf,smb_vwv4,(numtowrite>>16)&1); show_msg(aio_ex->outbuf); if (!srv_send_smb(smbd_server_fd(),aio_ex->outbuf, + true, aio_ex->req->seqnum+1, IS_CONN_ENCRYPTED(fsp->conn), &req->pcd)) { exit_server_cleanly("handle_aio_write: srv_send_smb " @@ -310,8 +310,6 @@ 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->req->mid); } outstanding_aio_calls++; @@ -347,7 +345,6 @@ 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->req->mid, false); return 0; } @@ -378,6 +375,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex) smb_setlen(outbuf,outsize - 4); show_msg(outbuf); if (!srv_send_smb(smbd_server_fd(),outbuf, + true, aio_ex->req->seqnum+1, IS_CONN_ENCRYPTED(aio_ex->fsp->conn), NULL)) { exit_server_cleanly("handle_aio_read_complete: srv_send_smb " "failed."); @@ -441,7 +439,6 @@ 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->req->mid, false); return 0; } @@ -475,7 +472,9 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex) } show_msg(outbuf); - if (!srv_send_smb(smbd_server_fd(),outbuf,IS_CONN_ENCRYPTED(fsp->conn), + if (!srv_send_smb(smbd_server_fd(),outbuf, + true, aio_ex->req->seqnum+1, + IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("handle_aio_write: srv_send_smb failed."); } @@ -534,7 +533,6 @@ void smbd_aio_complete_mid(unsigned int mid) if (!aio_ex) { DEBUG(3,("smbd_aio_complete_mid: Can't find record to " "match mid %u.\n", mid)); - srv_cancel_sign_response(mid, false); return; } @@ -544,7 +542,6 @@ void smbd_aio_complete_mid(unsigned int mid) * ignore. */ DEBUG( 3,( "smbd_aio_complete_mid: file closed whilst " "aio outstanding (mid[%u]).\n", mid)); - srv_cancel_sign_response(mid, false); return; } diff --git a/source3/smbd/avahi_register.c b/source3/smbd/avahi_register.c new file mode 100644 index 0000000000..1903b0ef96 --- /dev/null +++ b/source3/smbd/avahi_register.c @@ -0,0 +1,170 @@ +/* + * Unix SMB/CIFS implementation. + * Register _smb._tcp with avahi + * + * Copyright (C) Volker Lendecke 2009 + * + * 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 <avahi-client/client.h> +#include <avahi-client/publish.h> +#include <avahi-common/error.h> + +struct avahi_state_struct { + struct AvahiPoll *poll; + AvahiClient *client; + AvahiEntryGroup *entry_group; + uint16_t port; +}; + +static void avahi_entry_group_callback(AvahiEntryGroup *g, + AvahiEntryGroupState status, + void *userdata) +{ + struct avahi_state_struct *state = talloc_get_type_abort( + userdata, struct avahi_state_struct); + int error; + + switch (status) { + case AVAHI_ENTRY_GROUP_ESTABLISHED: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_ESTABLISHED\n")); + break; + case AVAHI_ENTRY_GROUP_FAILURE: + error = avahi_client_errno(state->client); + + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_FAILURE: %s\n", + avahi_strerror(error))); + break; + case AVAHI_ENTRY_GROUP_COLLISION: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_COLLISION\n")); + break; + case AVAHI_ENTRY_GROUP_UNCOMMITED: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_UNCOMMITED\n")); + break; + case AVAHI_ENTRY_GROUP_REGISTERING: + DEBUG(10, ("avahi_entry_group_callback: " + "AVAHI_ENTRY_GROUP_REGISTERING\n")); + break; + } +} + +static void avahi_client_callback(AvahiClient *c, AvahiClientState status, + void *userdata) +{ + struct avahi_state_struct *state = talloc_get_type_abort( + userdata, struct avahi_state_struct); + int error; + + switch (status) { + case AVAHI_CLIENT_S_RUNNING: + DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_S_RUNNING\n")); + + state->entry_group = avahi_entry_group_new( + c, avahi_entry_group_callback, state); + if (state->entry_group == NULL) { + error = avahi_client_errno(c); + DEBUG(10, ("avahi_entry_group_new failed: %s\n", + avahi_strerror(error))); + break; + } + if (avahi_entry_group_add_service( + state->entry_group, AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, 0, global_myname(), + "_smb._tcp", NULL, NULL, state->port, NULL) < 0) { + error = avahi_client_errno(c); + DEBUG(10, ("avahi_entry_group_add_service failed: " + "%s\n", avahi_strerror(error))); + avahi_entry_group_free(state->entry_group); + state->entry_group = NULL; + break; + } + if (avahi_entry_group_commit(state->entry_group) < 0) { + error = avahi_client_errno(c); + DEBUG(10, ("avahi_entry_group_commit failed: " + "%s\n", avahi_strerror(error))); + avahi_entry_group_free(state->entry_group); + state->entry_group = NULL; + break; + } + break; + case AVAHI_CLIENT_FAILURE: + error = avahi_client_errno(c); + + DEBUG(10, ("avahi_client_callback: AVAHI_CLIENT_FAILURE: %s\n", + avahi_strerror(error))); + + if (error != AVAHI_ERR_DISCONNECTED) { + break; + } + avahi_client_free(c); + state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL, + avahi_client_callback, state, + &error); + if (state->client == NULL) { + DEBUG(10, ("avahi_client_new failed: %s\n", + avahi_strerror(error))); + break; + } + break; + case AVAHI_CLIENT_S_COLLISION: + DEBUG(10, ("avahi_client_callback: " + "AVAHI_CLIENT_S_COLLISION\n")); + break; + case AVAHI_CLIENT_S_REGISTERING: + DEBUG(10, ("avahi_client_callback: " + "AVAHI_CLIENT_S_REGISTERING\n")); + break; + case AVAHI_CLIENT_CONNECTING: + DEBUG(10, ("avahi_client_callback: " + "AVAHI_CLIENT_CONNECTING\n")); + break; + } +} + +void *avahi_start_register(TALLOC_CTX *mem_ctx, struct tevent_context *ev, + uint16_t port) +{ + struct avahi_state_struct *state; + int error; + + state = talloc(mem_ctx, struct avahi_state_struct); + if (state == NULL) { + return state; + } + state->port = port; + state->poll = tevent_avahi_poll(state, ev); + if (state->poll == NULL) { + goto fail; + } + state->client = avahi_client_new(state->poll, AVAHI_CLIENT_NO_FAIL, + avahi_client_callback, state, + &error); + if (state->client == NULL) { + DEBUG(10, ("avahi_client_new failed: %s\n", + avahi_strerror(error))); + goto fail; + } + return state; + + fail: + TALLOC_FREE(state); + return NULL; +} diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c index 42849931f3..4c61428692 100644 --- a/source3/smbd/blocking.c +++ b/source3/smbd/blocking.c @@ -204,9 +204,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck, (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(blr->req->mid); - return True; } @@ -260,6 +257,7 @@ static void generic_blocking_lock_error(struct blocking_lock_record *blr, NTSTAT reply_nterror(blr->req, status); if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf, + true, blr->req->seqnum+1, blr->req->encrypted, NULL)) { exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed."); } @@ -343,6 +341,7 @@ static void blocking_lock_reply_error(struct blocking_lock_record *blr, NTSTATUS if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf, + true, blr->req->seqnum+1, IS_CONN_ENCRYPTED(blr->fsp->conn), NULL)) { exit_server_cleanly("blocking_lock_reply_error: " diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h index 6ac92ed3dd..b646bc30fd 100644 --- a/source3/smbd/globals.h +++ b/source3/smbd/globals.h @@ -202,6 +202,7 @@ extern int num_children; struct smbd_server_connection { struct fd_event *fde; uint64_t num_requests; + struct smb_signing_state *signing_state; }; extern struct smbd_server_connection *smbd_server_conn; diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index f20c851297..d39aab4f47 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -134,6 +134,7 @@ void send_trans_reply(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) { exit_server_cleanly("send_trans_reply: srv_send_smb failed."); } @@ -190,6 +191,7 @@ void send_trans_reply(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) exit_server_cleanly("send_trans_reply: srv_send_smb " "failed."); @@ -296,6 +298,7 @@ static void api_dcerpc_cmd_write_done(struct tevent_req *subreq) send: if (!srv_send_smb( smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn) || req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); @@ -322,6 +325,7 @@ static void api_dcerpc_cmd_read_done(struct tevent_req *subreq) reply_nterror(req, status); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn) ||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb " diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c index a921954c49..e548c587c1 100644 --- a/source3/smbd/negprot.c +++ b/source3/smbd/negprot.c @@ -316,7 +316,7 @@ static void reply_nt1(struct smb_request *req, uint16 choice) capabilities &= ~CAP_RAW_MODE; if (lp_server_signing() == Required) secword |=NEGOTIATE_SECURITY_SIGNATURES_REQUIRED; - srv_set_signing_negotiated(); + srv_set_signing_negotiated(smbd_server_conn); } else { DEBUG(0,("reply_nt1: smb signing is incompatible with share level security !\n")); if (lp_server_signing() == Required) { diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index 8ceeaf5f55..fdab2ca848 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -143,7 +143,9 @@ static void change_notify_reply_packet(connection_struct *conn, } show_msg((char *)req->outbuf); - if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + if (!srv_send_smb(smbd_server_fd(), + (char *)req->outbuf, + true, req->seqnum+1, req->encrypted, &req->pcd)) { exit_server_cleanly("change_notify_reply_packet: srv_send_smb " "failed."); @@ -260,9 +262,6 @@ NTSTATUS change_notify_add_request(struct smb_request *req, 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(request->req->mid); - return NT_STATUS_OK; } diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9c7fb1914e..7e75eea6b4 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -230,6 +230,7 @@ void send_nt_replies(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) { exit_server_cleanly("send_nt_replies: srv_send_smb failed."); @@ -440,6 +441,8 @@ void reply_ntcreate_and_X(struct smb_request *req) START_PROFILE(SMBntcreateX); + SET_STAT_INVALID(sbuf); + if (req->wct < 24) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); return; @@ -864,6 +867,8 @@ static void call_nt_transact_create(connection_struct *conn, uint8_t oplock_granted; TALLOC_CTX *ctx = talloc_tos(); + SET_STAT_INVALID(sbuf); + DEBUG(5,("call_nt_transact_create\n")); /* @@ -1129,9 +1134,9 @@ void reply_ntcancel(struct smb_request *req) */ START_PROFILE(SMBntcancel); + srv_cancel_sign_response(smbd_server_conn); remove_pending_change_notify_requests_by_mid(req->mid); remove_pending_lock_requests_by_mid(req->mid); - srv_cancel_sign_response(req->mid, true); DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid)); diff --git a/source3/smbd/open.c b/source3/smbd/open.c index d529b009d5..52df4fa143 100644 --- a/source3/smbd/open.c +++ b/source3/smbd/open.c @@ -1033,15 +1033,6 @@ static void defer_open(struct share_mode_lock *lck, exit_server("push_deferred_smb_message failed"); } add_deferred_open(lck, req->mid, request_time, state->id); - - /* - * Push the MID of this packet on the signing queue. - * We only do this once, the first time we push the packet - * onto the deferred open queue, as this has a side effect - * of incrementing the response sequence number. - */ - - srv_defer_sign_response(req->mid); } diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 22870283fa..ce00397bbd 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -361,7 +361,6 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx struct share_mode_entry msg; files_struct *fsp; char *break_msg; - bool sign_state; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -423,20 +422,14 @@ void process_oplock_async_level2_break_message(struct messaging_context *msg_ctx wait_before_sending_break(); } - /* Save the server smb signing state. */ - sign_state = srv_oplock_set_signing(False); - show_msg(break_msg); if (!srv_send_smb(smbd_server_fd(), - break_msg, + break_msg, false, 0, IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("oplock_break: srv_send_smb failed."); } - /* Restore the sign state to what it was. */ - srv_oplock_set_signing(sign_state); - TALLOC_FREE(break_msg); /* Async level2 request, don't send a reply, just remove the oplock. */ @@ -457,7 +450,6 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, files_struct *fsp; char *break_msg; bool break_to_level2 = False; - bool sign_state; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -530,20 +522,14 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, wait_before_sending_break(); } - /* Save the server smb signing state. */ - sign_state = srv_oplock_set_signing(False); - show_msg(break_msg); if (!srv_send_smb(smbd_server_fd(), - break_msg, + break_msg, false, 0, IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("oplock_break: srv_send_smb failed."); } - /* Restore the sign state to what it was. */ - srv_oplock_set_signing(sign_state); - TALLOC_FREE(break_msg); fsp->sent_oplock_break = break_to_level2 ? LEVEL_II_BREAK_SENT:BREAK_TO_NONE_SENT; @@ -570,7 +556,6 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx, unsigned long file_id; files_struct *fsp; char *break_msg; - bool sign_state; if (data->data == NULL) { DEBUG(0, ("Got NULL buffer\n")); @@ -610,20 +595,14 @@ static void process_kernel_oplock_break(struct messaging_context *msg_ctx, exit_server("Could not talloc break_msg\n"); } - /* Save the server smb signing state. */ - sign_state = srv_oplock_set_signing(False); - show_msg(break_msg); if (!srv_send_smb(smbd_server_fd(), - break_msg, + break_msg, false, 0, IS_CONN_ENCRYPTED(fsp->conn), NULL)) { exit_server_cleanly("oplock_break: srv_send_smb failed."); } - /* Restore the sign state to what it was. */ - srv_oplock_set_signing(sign_state); - TALLOC_FREE(break_msg); fsp->sent_oplock_break = BREAK_TO_NONE_SENT; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 15d120a79c..076965e783 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -298,11 +298,13 @@ int register_existing_vuid(uint16 vuid, vuser->server_info->unix_name); } - if (srv_is_signing_negotiated() && !vuser->server_info->guest && - !srv_signing_started()) { + if (srv_is_signing_negotiated(smbd_server_conn) && + !vuser->server_info->guest) { /* Try and turn on server signing on the first non-guest * sessionsetup. */ - srv_set_signing(vuser->server_info->user_session_key, response_blob); + srv_set_signing(smbd_server_conn, + vuser->server_info->user_session_key, + response_blob); } /* fill in the current_user_info struct */ diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 2686cf41d9..7ae7435646 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -216,6 +216,7 @@ static void pipe_write_done(struct tevent_req *subreq) send: if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn)||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 18fbdd7939..65778ab0fc 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -32,16 +32,20 @@ static void construct_reply_common(struct smb_request *req, const char *inbuf, Send an smb to a fd. ****************************************************************************/ -bool srv_send_smb(int fd, char *buffer, bool do_encrypt, - struct smb_perfcount_data *pcd) +bool srv_send_smb(int fd, char *buffer, + bool do_signing, uint32_t seqnum, + bool do_encrypt, + struct smb_perfcount_data *pcd) { size_t len = 0; size_t nwritten=0; ssize_t ret; char *buf_out = buffer; - /* Sign the outgoing packet if required. */ - srv_calculate_sign_mac(buf_out); + if (do_signing) { + /* Sign the outgoing packet if required. */ + srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum); + } if (do_encrypt) { NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out); @@ -275,7 +279,7 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, if (CVAL(lenbuf,0) == 0 && min_recv_size && (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */ (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) && - !srv_is_signing_active()) { + !srv_is_signing_active(smbd_server_conn)) { return receive_smb_raw_talloc_partial_read( mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen); @@ -311,7 +315,8 @@ static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd, static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer, unsigned int timeout, size_t *p_unread, bool *p_encrypted, - size_t *p_len) + size_t *p_len, + uint32_t *seqnum) { size_t len = 0; NTSTATUS status; @@ -336,7 +341,7 @@ static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, } /* Check the incoming SMB signature. */ - if (!srv_check_sign_mac(*buffer, true)) { + if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) { DEBUG(0, ("receive_smb: SMB Signature verification failed on " "incoming packet!\n")); return NT_STATUS_INVALID_NETWORK_RESPONSE; @@ -366,6 +371,7 @@ void init_smb_request(struct smb_request *req, req->flags2 = SVAL(inbuf, smb_flg2); req->smbpid = SVAL(inbuf, smb_pid); req->mid = SVAL(inbuf, smb_mid); + req->seqnum = 0; req->vuid = SVAL(inbuf, smb_uid); req->tid = SVAL(inbuf, smb_tid); req->wct = CVAL(inbuf, smb_wct); @@ -401,7 +407,8 @@ void init_smb_request(struct smb_request *req, static void process_smb(struct smbd_server_connection *conn, uint8_t *inbuf, size_t nread, size_t unread_bytes, - bool encrypted, struct smb_perfcount_data *deferred_pcd); + uint32_t seqnum, bool encrypted, + struct smb_perfcount_data *deferred_pcd); static void smbd_deferred_open_timer(struct event_context *ev, struct timed_event *te, @@ -427,7 +434,7 @@ static void smbd_deferred_open_timer(struct event_context *ev, process_smb(smbd_server_conn, inbuf, msg->buf.length, 0, - msg->encrypted, &msg->pcd); + msg->seqnum, msg->encrypted, &msg->pcd); } /**************************************************************************** @@ -458,6 +465,7 @@ static bool push_queued_message(struct smb_request *req, } msg->request_time = request_time; + msg->seqnum = req->seqnum; msg->encrypted = req->encrypted; SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd); @@ -913,7 +921,7 @@ static const struct smb_message_struct { /* 0x30 */ { NULL, NULL, 0 }, /* 0x31 */ { NULL, NULL, 0 }, /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC }, -/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER}, +/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC }, /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER}, /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER}, /* 0x36 */ { NULL, NULL, 0 }, @@ -1362,7 +1370,7 @@ 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, + uint32_t seqnum, bool encrypted, struct smb_perfcount_data *deferred_pcd) { connection_struct *conn; @@ -1374,6 +1382,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted); req->inbuf = (uint8_t *)talloc_move(req, &inbuf); + req->seqnum = seqnum; /* we popped this message off the queue - keep original perf data */ if (deferred_pcd) @@ -1405,6 +1414,7 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn)||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); @@ -1420,7 +1430,8 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, ****************************************************************************/ static void process_smb(struct smbd_server_connection *conn, uint8_t *inbuf, size_t nread, size_t unread_bytes, - bool encrypted, struct smb_perfcount_data *deferred_pcd) + uint32_t seqnum, bool encrypted, + struct smb_perfcount_data *deferred_pcd) { int msg_type = CVAL(inbuf,0); @@ -1442,7 +1453,7 @@ static void process_smb(struct smbd_server_connection *conn, show_msg((char *)inbuf); - construct_reply((char *)inbuf,nread,unread_bytes,encrypted,deferred_pcd); + construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd); trans_num++; done: @@ -1637,6 +1648,7 @@ void chain_reply(struct smb_request *req) talloc_get_size(req->chain_outbuf) - 4); if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn) ||req->encrypted, &req->pcd)) { @@ -1761,6 +1773,7 @@ void chain_reply(struct smb_request *req) show_msg((char *)(req->chain_outbuf)); if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(req->conn)||req->encrypted, &req->pcd)) { exit_server_cleanly("construct_reply: srv_send_smb failed."); @@ -1830,6 +1843,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c bool encrypted = false; TALLOC_CTX *mem_ctx = talloc_tos(); NTSTATUS status; + uint32_t seqnum; /* TODO: make this completely nonblocking */ @@ -1838,7 +1852,7 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c 0, /* timeout */ &unread_bytes, &encrypted, - &inbuf_len); + &inbuf_len, &seqnum); if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) { goto process; } @@ -1850,7 +1864,8 @@ static void smbd_server_connection_read_handler(struct smbd_server_connection *c } process: - process_smb(conn, inbuf, inbuf_len, unread_bytes, encrypted, NULL); + process_smb(conn, inbuf, inbuf_len, unread_bytes, + seqnum, encrypted, NULL); } static void smbd_server_connection_handler(struct event_context *ev, @@ -2015,7 +2030,8 @@ void smbd_process(void) unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; DEBUG( 1, ("Connection denied from %s\n", client_addr(get_client_fd(),addr,sizeof(addr)) ) ); - (void)srv_send_smb(smbd_server_fd(),(char *)buf,false, NULL); + (void)srv_send_smb(smbd_server_fd(),(char *)buf, false, + 0, false, NULL); exit_server_cleanly("connection denied"); } @@ -2041,6 +2057,10 @@ void smbd_process(void) DEBUG(0,("Changed root to %s\n", lp_rootdir())); } + if (!srv_init_signing(smbd_server_conn)) { + exit_server("Failed to init smb_signing"); + } + /* Setup oplocks */ if (!init_oplocks(smbd_messaging_context())) exit_server("Failed to init oplocks"); diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 8b560bd8ca..3f9d5c5498 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -497,7 +497,7 @@ void reply_special(char *inbuf) DEBUG(5,("init msg_type=0x%x msg_flags=0x%x\n", msg_type, msg_flags)); - srv_send_smb(smbd_server_fd(), outbuf, false, NULL); + srv_send_smb(smbd_server_fd(), outbuf, false, 0, false, NULL); return; } @@ -1606,6 +1606,8 @@ void reply_open(struct smb_request *req) START_PROFILE(SMBopen); + SET_STAT_INVALID(sbuf); + if (req->wct < 2) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); END_PROFILE(SMBopen); @@ -1741,6 +1743,8 @@ void reply_open_and_X(struct smb_request *req) return; } + SET_STAT_INVALID(sbuf); + open_flags = SVAL(req->vwv+2, 0); deny_mode = SVAL(req->vwv+3, 0); smb_attr = SVAL(req->vwv+5, 0); @@ -1945,6 +1949,7 @@ void reply_mknew(struct smb_request *req) START_PROFILE(SMBcreate); ZERO_STRUCT(ft); + SET_STAT_INVALID(sbuf); if (req->wct < 3) { reply_nterror(req, NT_STATUS_INVALID_PARAMETER); @@ -2123,6 +2128,7 @@ void reply_ctemp(struct smb_request *req) return; } + SET_STAT_INVALID(sbuf); SMB_VFS_STAT(conn,fname,&sbuf); /* We should fail if file does not exist. */ @@ -2673,6 +2679,7 @@ static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, return (ssize_t)nread; } +#if defined(WITH_SENDFILE) /**************************************************************************** Deal with the case of sendfile reading less bytes from the file than requested. Fill with zeros (all we can do). @@ -2729,6 +2736,7 @@ static void sendfile_short_send(files_struct *fsp, SAFE_FREE(buf); } } +#endif /* defined WITH_SENDFILE */ /**************************************************************************** Return a readbraw error (4 bytes of zero). @@ -2766,7 +2774,8 @@ static void send_file_readbraw(connection_struct *conn, */ if ( !req_is_in_chain(req) && (nread > 0) && (fsp->base_fsp == NULL) && - (fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) { + (fsp->wcp == NULL) && + lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) { ssize_t sendfile_read = -1; char header[4]; DATA_BLOB header_blob; @@ -2870,7 +2879,8 @@ void reply_readbraw(struct smb_request *req) START_PROFILE(SMBreadbraw); - if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) { + if (srv_is_signing_active(smbd_server_conn) || + is_encrypted_packet(req->inbuf)) { exit_server_cleanly("reply_readbraw: SMB signing/sealing is active - " "raw reads/writes are disallowed."); } @@ -3274,7 +3284,8 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req, if (!req_is_in_chain(req) && !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) && - lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) { + (fsp->wcp == NULL) && + lp_use_sendfile(SNUM(conn), smbd_server_conn->signing_state) ) { uint8 headerbuf[smb_size + 12 * 2]; DATA_BLOB header; @@ -3450,7 +3461,8 @@ void reply_read_and_X(struct smb_request *req) return; } /* We currently don't do this on signed or sealed data. */ - if (srv_is_signing_active() || is_encrypted_packet(req->inbuf)) { + if (srv_is_signing_active(smbd_server_conn) || + is_encrypted_packet(req->inbuf)) { reply_nterror(req, NT_STATUS_NOT_SUPPORTED); END_PROFILE(SMBreadX); return; @@ -3558,7 +3570,7 @@ void reply_writebraw(struct smb_request *req) */ SCVAL(req->inbuf,smb_com,SMBwritec); - if (srv_is_signing_active()) { + if (srv_is_signing_active(smbd_server_conn)) { END_PROFILE(SMBwritebraw); exit_server_cleanly("reply_writebraw: SMB signing is active - " "raw reads/writes are disallowed."); @@ -3653,9 +3665,10 @@ void reply_writebraw(struct smb_request *req) SSVALS(buf,smb_vwv0,0xFFFF); show_msg(buf); if (!srv_send_smb(smbd_server_fd(), - buf, - IS_CONN_ENCRYPTED(conn), - &req->pcd)) { + buf, + false, 0, /* no signing */ + IS_CONN_ENCRYPTED(conn), + &req->pcd)) { exit_server_cleanly("reply_writebraw: srv_send_smb " "failed."); } @@ -4757,6 +4770,7 @@ void reply_echo(struct smb_request *req) show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn)||req->encrypted, cur_pcd)) exit_server_cleanly("reply_echo: srv_send_smb failed."); diff --git a/source3/smbd/server.c b/source3/smbd/server.c index d27f98281b..67836f785b 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -643,8 +643,19 @@ static bool open_sockets_smbd(struct smbd_parent_context *parent, #endif if (dns_port != 0) { +#ifdef WITH_DNSSD_SUPPORT smbd_setup_mdns_registration(smbd_event_context(), parent, dns_port); +#endif +#ifdef WITH_AVAHI_SUPPORT + void *avahi_conn; + + avahi_conn = avahi_start_register( + smbd_event_context(), smbd_event_context(), dns_port); + if (avahi_conn == NULL) { + DEBUG(10, ("avahi_start_register failed\n")); + } +#endif } return true; diff --git a/source3/smbd/service.c b/source3/smbd/service.c index eb16a2601e..e33f04d971 100644 --- a/source3/smbd/service.c +++ b/source3/smbd/service.c @@ -1110,7 +1110,7 @@ static connection_struct *make_connection_snum(int snum, user_struct *vuser, if( DEBUGLVL( IS_IPC(conn) ? 3 : 1 ) ) { dbgtext( "%s (%s) ", get_remote_machine_name(), conn->client_address ); - dbgtext( "%s", srv_is_signing_active() ? "signed " : ""); + dbgtext( "%s", srv_is_signing_active(smbd_server_conn) ? "signed " : ""); dbgtext( "connect to service %s ", lp_servicename(snum) ); dbgtext( "initially as user %s ", conn->server_info->unix_name ); diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index 2c29192220..e8878a29ab 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -91,25 +91,6 @@ static int push_signature(uint8 **outbuf) } /**************************************************************************** - Start the signing engine if needed. Don't fail signing here. -****************************************************************************/ - -static void sessionsetup_start_signing_engine( - const auth_serversupplied_info *server_info, - const uint8 *inbuf) -{ - if (!server_info->guest && !srv_signing_started()) { - /* We need to start the signing engine - * here but a W2K client sends the old - * "BSRSPYL " signature instead of the - * correct one. Subsequent packets will - * be correct. - */ - srv_check_sign_mac((char *)inbuf, False); - } -} - -/**************************************************************************** Send a security blob via a session setup reply. ****************************************************************************/ @@ -579,7 +560,6 @@ static void reply_spnego_kerberos(struct smb_request *req, SSVAL(req->outbuf, smb_uid, sess_vuid); - sessionsetup_start_signing_engine(server_info, req->inbuf); /* Successful logon. Keep this vuid. */ *p_invalidate_vuid = False; } @@ -668,9 +648,6 @@ static void reply_spnego_ntlmssp(struct smb_request *req, if (server_info->guest) { SSVAL(req->outbuf,smb_vwv2,1); } - - sessionsetup_start_signing_engine(server_info, - (uint8 *)req->inbuf); } out: @@ -1804,8 +1781,6 @@ void reply_sesssetup_and_X(struct smb_request *req) /* current_user_info is changed on new vuid */ reload_services( True ); - - sessionsetup_start_signing_engine(server_info, req->inbuf); } data_blob_free(&nt_resp); diff --git a/source3/smbd/signing.c b/source3/smbd/signing.c new file mode 100644 index 0000000000..b56eb71f45 --- /dev/null +++ b/source3/smbd/signing.c @@ -0,0 +1,158 @@ +/* + Unix SMB/CIFS implementation. + SMB Signing Code + Copyright (C) Jeremy Allison 2003. + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2002-2003 + Copyright (C) Stefan Metzmacher 2009 + + 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 "smbd/globals.h" + + +/*********************************************************** + Called to validate an incoming packet from the client. +************************************************************/ + +bool srv_check_sign_mac(struct smbd_server_connection *conn, + const char *inbuf, uint32_t *seqnum) +{ + /* Check if it's a non-session message. */ + if(CVAL(inbuf,0)) { + return true; + } + + *seqnum = smb_signing_next_seqnum(conn->signing_state, false); + return smb_signing_check_pdu(conn->signing_state, + (const uint8_t *)inbuf, + *seqnum); +} + +/*********************************************************** + Called to sign an outgoing packet to the client. +************************************************************/ + +void srv_calculate_sign_mac(struct smbd_server_connection *conn, + char *outbuf, uint32_t seqnum) +{ + /* Check if it's a non-session message. */ + if(CVAL(outbuf,0)) { + return; + } + + smb_signing_sign_pdu(conn->signing_state, (uint8_t *)outbuf, seqnum); +} + + +/*********************************************************** + Called to indicate a oneway request +************************************************************/ +void srv_cancel_sign_response(struct smbd_server_connection *conn) +{ + smb_signing_cancel_reply(conn->signing_state, true); +} + +/*********************************************************** + Called by server negprot when signing has been negotiated. +************************************************************/ + +bool srv_init_signing(struct smbd_server_connection *conn) +{ + bool allowed = true; + bool mandatory = false; + + switch (lp_server_signing()) { + case Required: + mandatory = true; + break; + case Auto: + break; + case True: + break; + case False: + allowed = false; + break; + } + + conn->signing_state = smb_signing_init(smbd_event_context(), + allowed, mandatory); + if (!conn->signing_state) { + return false; + } + + return true; +} + +void srv_set_signing_negotiated(struct smbd_server_connection *conn) +{ + smb_signing_set_negotiated(conn->signing_state); +} + +/*********************************************************** + Returns whether signing is active. We can't use sendfile or raw + reads/writes if it is. +************************************************************/ + +bool srv_is_signing_active(struct smbd_server_connection *conn) +{ + return smb_signing_is_active(conn->signing_state); +} + + +/*********************************************************** + Returns whether signing is negotiated. We can't use it unless it was + in the negprot. +************************************************************/ + +bool srv_is_signing_negotiated(struct smbd_server_connection *conn) +{ + return smb_signing_is_negotiated(conn->signing_state); +} + +/*********************************************************** + Turn on signing from this packet onwards. +************************************************************/ + +void srv_set_signing(struct smbd_server_connection *conn, + const DATA_BLOB user_session_key, + const DATA_BLOB response) +{ + bool negotiated; + bool mandatory; + + if (!user_session_key.length) + return; + + negotiated = smb_signing_is_negotiated(conn->signing_state); + mandatory = smb_signing_is_mandatory(conn->signing_state); + + if (!negotiated && !mandatory) { + DEBUG(5,("srv_set_signing: signing negotiated = %u, " + "mandatory_signing = %u. Not allowing smb signing.\n", + negotiated, mandatory)); + return; + } + + if (!smb_signing_activate(conn->signing_state, + user_session_key, response)) { + return; + } + + DEBUG(3,("srv_set_signing: turning on SMB signing: " + "signing negotiated = %u, mandatory_signing = %u.\n", + negotiated, mandatory)); +} + diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index ee1dda98b2..04b1145e58 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -832,6 +832,7 @@ void send_trans2_replies(connection_struct *conn, show_msg((char *)req->outbuf); if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf, + true, req->seqnum+1, IS_CONN_ENCRYPTED(conn), &req->pcd)) exit_server_cleanly("send_trans2_replies: srv_send_smb failed."); @@ -894,6 +895,8 @@ static void call_trans2open(connection_struct *conn, uint32 create_options = 0; TALLOC_CTX *ctx = talloc_tos(); + SET_STAT_INVALID(sbuf); + /* * Ensure we have enough parameters to perform the operation. */ @@ -2892,8 +2895,8 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned case SMB_QUERY_CIFS_UNIX_INFO: { bool large_write = lp_min_receive_file_size() && - !srv_is_signing_active(); - bool large_read = !srv_is_signing_active(); + !srv_is_signing_active(smbd_server_conn); + bool large_read = !srv_is_signing_active(smbd_server_conn); int encrypt_caps = 0; if (!lp_unix_extensions()) { diff --git a/source3/torture/torture.c b/source3/torture/torture.c index 6029eb0727..1b9e394a68 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -5203,7 +5203,7 @@ static bool run_cli_echo(int dummy) struct async_req *req; NTSTATUS status; - printf("starting chain1 test\n"); + printf("starting cli_echo test\n"); if (!torture_open_connection(&cli, 0)) { return false; } diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index d83fb44aba..21881ba6a9 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -54,7 +54,7 @@ NTSTATUS net_get_remote_domain_sid(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_SID **domain_sid, const char **domain_name) { - struct rpc_pipe_client *lsa_pipe; + struct rpc_pipe_client *lsa_pipe = NULL; struct policy_handle pol; NTSTATUS result = NT_STATUS_OK; union lsa_PolicyInformation *info = NULL; @@ -1657,7 +1657,7 @@ static NTSTATUS get_sid_from_name(struct cli_state *cli, { DOM_SID *sids = NULL; enum lsa_SidType *types = NULL; - struct rpc_pipe_client *pipe_hnd; + struct rpc_pipe_client *pipe_hnd = NULL; struct policy_handle lsa_pol; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; diff --git a/source3/utils/net_rpc_printer.c b/source3/utils/net_rpc_printer.c index b25c897770..9721628f02 100644 --- a/source3/utils/net_rpc_printer.c +++ b/source3/utils/net_rpc_printer.c @@ -84,7 +84,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value) switch(value.type) { case REG_DWORD: d_printf("\t[%s:%s]: REG_DWORD: 0x%08x\n", subkey, value.valuename, - *((uint32 *) value.data_p)); + *((uint32_t *) value.data_p)); break; case REG_SZ: @@ -105,7 +105,7 @@ static void display_reg_value(const char *subkey, REGISTRY_VALUE value) break; case REG_MULTI_SZ: { - uint32 i, num_values; + uint32_t i, num_values; char **values; if (!W_ERROR_IS_OK(reg_pull_multi_sz(NULL, value.data_p, @@ -158,7 +158,7 @@ NTSTATUS net_copy_fileattr(struct net_context *c, int fnum_src = 0; int fnum_dst = 0; SEC_DESC *sd = NULL; - uint16 attr; + uint16_t attr; time_t f_atime, f_ctime, f_mtime; @@ -654,9 +654,9 @@ static NTSTATUS copy_print_driver_3(struct net_context *c, static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, char *name, - uint32 flags, - uint32 level, - uint32 *num_printers, + uint32_t flags, + uint32_t level, + uint32_t *num_printers, union spoolss_PrinterInfo **info) { WERROR result; @@ -681,7 +681,7 @@ static bool net_spoolss_enum_printers(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, const char *printername, - uint32 access_required, + uint32_t access_required, const char *username, struct policy_handle *hnd) { @@ -723,7 +723,7 @@ static bool net_spoolss_open_printer_ex(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, struct policy_handle *hnd, - uint32 level, + uint32_t level, union spoolss_PrinterInfo *info) { WERROR result; @@ -745,7 +745,7 @@ static bool net_spoolss_getprinter(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_setprinter(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, struct policy_handle *hnd, - uint32 level, + uint32_t level, union spoolss_PrinterInfo *info) { WERROR result; @@ -863,7 +863,7 @@ static bool net_spoolss_enumprinterkey(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterdataex(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - uint32 offered, + uint32_t offered, struct policy_handle *hnd, const char *keyname, uint32_t *count, @@ -941,8 +941,8 @@ static bool net_spoolss_enumforms(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - uint32 level, const char *env, - uint32 *count, + uint32_t level, const char *env, + uint32_t *count, union spoolss_DriverInfo **info) { WERROR result; @@ -965,7 +965,7 @@ static bool net_spoolss_enumprinterdrivers (struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, TALLOC_CTX *mem_ctx, - struct policy_handle *hnd, uint32 level, + struct policy_handle *hnd, uint32_t level, const char *env, int version, union spoolss_DriverInfo *info) { @@ -999,7 +999,7 @@ static bool net_spoolss_getprinterdriver(struct rpc_pipe_client *pipe_hnd, static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, - TALLOC_CTX *mem_ctx, uint32 level, + TALLOC_CTX *mem_ctx, uint32_t level, union spoolss_DriverInfo *info) { WERROR result; @@ -1039,7 +1039,7 @@ static bool net_spoolss_addprinterdriver(struct rpc_pipe_client *pipe_hnd, } /** - * abstraction function to get uint32 num_printers and PRINTER_INFO_CTR ctr + * abstraction function to get uint32_t num_printers and PRINTER_INFO_CTR ctr * for a single printer or for all printers depending on argc/argv **/ @@ -1048,7 +1048,7 @@ static bool get_printer_info(struct rpc_pipe_client *pipe_hnd, int level, int argc, const char **argv, - uint32 *num_printers, + uint32_t *num_printers, union spoolss_PrinterInfo **info_p) { struct policy_handle hnd; @@ -1114,8 +1114,8 @@ NTSTATUS rpc_printer_list_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, num_printers; - uint32 level = 2; + uint32_t i, num_printers; + uint32_t level = 2; const char *printername, *sharename; union spoolss_PrinterInfo *info; @@ -1166,8 +1166,8 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i; - uint32 level = 3; + uint32_t i; + uint32_t level = 3; union spoolss_DriverInfo *info; int d; @@ -1175,7 +1175,7 @@ NTSTATUS rpc_printer_driver_list_internals(struct net_context *c, for (i=0; archi_table[i].long_archi!=NULL; i++) { - uint32 num_drivers; + uint32_t num_drivers; /* enum remote drivers */ if (!net_spoolss_enumprinterdrivers(pipe_hnd, mem_ctx, level, @@ -1225,11 +1225,11 @@ static NTSTATUS rpc_printer_publish_internals_args(struct rpc_pipe_client *pipe_ TALLOC_CTX *mem_ctx, int argc, const char **argv, - uint32 action) + uint32_t action) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, num_printers; - uint32 level = 7; + uint32_t i, num_printers; + uint32_t level = 7; const char *printername, *sharename; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; @@ -1373,8 +1373,8 @@ NTSTATUS rpc_printer_publish_list_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, num_printers; - uint32 level = 7; + uint32_t i, num_printers; + uint32_t level = 7; const char *printername, *sharename; union spoolss_PrinterInfo *info_enum; union spoolss_PrinterInfo info; @@ -1465,9 +1465,9 @@ NTSTATUS rpc_printer_migrate_security_internals(struct net_context *c, convince jerry that we should add clientside setacls level 3 at least */ NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i = 0; - uint32 num_printers; - uint32 level = 2; + uint32_t i = 0; + uint32_t num_printers; + uint32_t level = 2; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct policy_handle hnd_src, hnd_dst; @@ -1611,9 +1611,9 @@ NTSTATUS rpc_printer_migrate_forms_internals(struct net_context *c, { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; WERROR result; - uint32 i, f; - uint32 num_printers; - uint32 level = 1; + uint32_t i, f; + uint32_t num_printers; + uint32_t level = 1; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct policy_handle hnd_src, hnd_dst; @@ -1771,9 +1771,9 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, const char **argv) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i, p; - uint32 num_printers; - uint32 level = 3; + uint32_t i, p; + uint32_t num_printers; + uint32_t level = 3; const char *printername, *sharename; bool got_src_driver_share = false; bool got_dst_driver_share = false; @@ -1902,7 +1902,7 @@ NTSTATUS rpc_printer_migrate_drivers_internals(struct net_context *c, } - if (strlen(drivername) == 0) { + if (!drivername || strlen(drivername) == 0) { DEBUGADD(1,("Did not get driver for printer %s\n", printername)); goto done; @@ -1983,8 +1983,8 @@ NTSTATUS rpc_printer_migrate_printers_internals(struct net_context *c, { WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i = 0, num_printers; - uint32 level = 2; + uint32_t i = 0, num_printers; + uint32_t level = 2; union spoolss_PrinterInfo info_dst, info_src; union spoolss_PrinterInfo *info_enum; struct cli_state *cli_dst = NULL; @@ -2139,9 +2139,9 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, WERROR result; NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; - uint32 i = 0, p = 0, j = 0; - uint32 num_printers; - uint32 level = 2; + uint32_t i = 0, p = 0, j = 0; + uint32_t num_printers; + uint32_t level = 2; const char *printername, *sharename; struct rpc_pipe_client *pipe_hnd_dst = NULL; struct policy_handle hnd_src, hnd_dst; @@ -2260,14 +2260,13 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, info_dst.info2.secdesc = NULL; #if 0 - if (asprintf(&devicename, "\\\\%s\\%s", longname, - printername) < 0) { + info_dst.info2.devmode.devicename = + talloc_asprintf(mem_ctx, "\\\\%s\\%s", + longname, printername); + if (!info_dst.info2.devmode.devicename) { nt_status = NT_STATUS_NO_MEMORY; goto done; } - - init_unistr(&ctr_dst.printers_2->devmode->devicename, - devicename); #endif if (!net_spoolss_setprinter(pipe_hnd_dst, mem_ctx, &hnd_dst, level, &info_dst)) @@ -2445,7 +2444,7 @@ NTSTATUS rpc_printer_migrate_settings_internals(struct net_context *c, value.type = REG_SZ; value.size = data.uni_str_len * 2; if (value.size) { - value.data_p = (uint8 *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size); + value.data_p = (uint8_t *)TALLOC_MEMDUP(mem_ctx, data.buffer, value.size); } else { value.data_p = NULL; } diff --git a/source3/winbindd/winbindd_pam.c b/source3/winbindd/winbindd_pam.c index 15d1b7e2bf..54bcac2b04 100644 --- a/source3/winbindd/winbindd_pam.c +++ b/source3/winbindd/winbindd_pam.c @@ -1854,7 +1854,7 @@ 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)) { - if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB || + 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, diff --git a/source4/auth/config.m4 b/source4/auth/config.m4 index fb9ee58c60..9735b17cac 100644 --- a/source4/auth/config.m4 +++ b/source4/auth/config.m4 @@ -28,6 +28,8 @@ if test x"$ac_cv_header_sasl_sasl_h" = x"yes" -a x"$ac_cv_lib_ext_sasl2_sasl_cli SASL_CPPFLAGS="$CPPFLAGS" SASL_LDFLAGS="$LDFLAGS" LIB_REMOVE_USR_LIB(SASL_LDFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(SASL_CPPFLAGS) + CFLAGS_REMOVE_USR_INCLUDE(SASL_CFLAGS) else SMB_ENABLE(cyrus_sasl,NO) fi diff --git a/source4/auth/credentials/credentials_krb5.h b/source4/auth/credentials/credentials_krb5.h index 0d0e9f330f..5e56752eb4 100644 --- a/source4/auth/credentials/credentials_krb5.h +++ b/source4/auth/credentials/credentials_krb5.h @@ -24,6 +24,7 @@ #define __CREDENTIALS_KRB5_H__ #include <gssapi/gssapi.h> +#include <gssapi/gssapi_krb5.h> #include <krb5.h> struct gssapi_creds_container { diff --git a/source4/auth/kerberos/clikrb5.c b/source4/auth/kerberos/clikrb5.c index cf87d13cf2..68e7eb90cc 100644 --- a/source4/auth/kerberos/clikrb5.c +++ b/source4/auth/kerberos/clikrb5.c @@ -74,13 +74,9 @@ void kerberos_free_data_contents(krb5_context context, krb5_data *pdata) { -#if defined(HAVE_KRB5_FREE_DATA_CONTENTS) if (pdata->data) { - krb5_free_data_contents(context, pdata); + krb5_data_free(pdata); } -#else - SAFE_FREE(pdata->data); -#endif } krb5_error_code smb_krb5_kt_free_entry(krb5_context context, krb5_keytab_entry *kt_entry) diff --git a/source4/build/m4/public.m4 b/source4/build/m4/public.m4 index bd98a400be..2bf63f0ca6 100644 --- a/source4/build/m4/public.m4 +++ b/source4/build/m4/public.m4 @@ -102,10 +102,12 @@ AC_DEFUN([SMB_EXT_LIB_FROM_PKGCONFIG], ac_cv_$1_libs_only_other="`$PKG_CONFIG --libs-only-other '$2'` `$PKG_CONFIG --libs-only-L '$2'`" LIB_REMOVE_USR_LIB(ac_cv_$1_libs_only_other) + ac_cv_$1_includedir_only="`$PKG_CONFIG --cflags-only-I '$2'`" + CFLAGS_REMOVE_USR_INCLUDE(ac_cv_$1_includedir_only) SMB_EXT_LIB($1, [`$PKG_CONFIG --libs-only-l '$2'`], [`$PKG_CONFIG --cflags-only-other '$2'`], - [`$PKG_CONFIG --cflags-only-I '$2'`], + [$ac_cv_$1_includedir_only], [$ac_cv_$1_libs_only_other]) ac_cv_$1_found=yes diff --git a/source4/build/make/rules.mk b/source4/build/make/rules.mk index 55ecf8968b..e9f4786d34 100644 --- a/source4/build/make/rules.mk +++ b/source4/build/make/rules.mk @@ -185,7 +185,8 @@ showflags:: base_srcdirs = $(srcdir) ../librpc/ ../lib/ ../libcli etags: - etags `find $(base_srcdirs) -name "*.[ch]"` + etags $(ETAGS_OPTIONS) `find $(base_srcdirs) -name "*.[ch]"` ctags: - ctags `find $(base_srcdirs) -name "*.[ch]"` + ctags $(CTAGS_OPTIONS) `find $(base_srcdirs) -name "*.[ch]"` + diff --git a/source4/configure.ac b/source4/configure.ac index 065a3300ca..3c23f27d68 100644 --- a/source4/configure.ac +++ b/source4/configure.ac @@ -44,14 +44,14 @@ AC_CONFIG_FILES(librpc/dcerpc_atsvc.pc) m4_include(min_versions.m4) -SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= $TALLOC_MIN_VERSION, [], +SMB_INCLUDED_LIB_PKGCONFIG(LIBTALLOC, talloc >= TALLOC_MIN_VERSION, [], [ m4_include(../lib/talloc/libtalloc.m4) SMB_INCLUDE_MK(../lib/talloc/config.mk) ] ) -SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= $TDB_MIN_VERSION, +SMB_INCLUDED_LIB_PKGCONFIG(LIBTDB, tdb >= TDB_MIN_VERSION, [], [ m4_include(../lib/tdb/libtdb.m4) @@ -67,7 +67,7 @@ SMB_INCLUDED_LIB_PKGCONFIG(LIBTEVENT, tevent = TEVENT_REQUIRED_VERSION, SMB_INCLUDE_MK(../lib/tevent/python.mk) -SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = $LDB_REQUIRED_VERSION, +SMB_INCLUDED_LIB_PKGCONFIG(LIBLDB, ldb = LDB_REQUIRED_VERSION, [ SMB_INCLUDE_MK(lib/ldb/ldb_ildap/config.mk) SMB_INCLUDE_MK(lib/ldb/tools/config.mk) diff --git a/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py new file mode 100755 index 0000000000..aab93e59a3 --- /dev/null +++ b/source4/dsdb/samdb/ldb_modules/tests/possibleinferiors.py @@ -0,0 +1,246 @@ +#!/usr/bin/python + +# Unix SMB/CIFS implementation. +# Copyright (C) Andrew Tridgell 2009 +# +# 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/>. +# + +"""Tests the possibleInferiors generation in the schema_fsmo ldb module""" + +import optparse +import sys + + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + +import samba +from samba import getopt as options, Ldb +import ldb + +parser = optparse.OptionParser("possibleinferiors.py <URL> [<CLASS>]") +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) +parser.add_option_group(options.VersionOptions(parser)) +parser.add_option("--wspp", action="store_true") + +opts, args = parser.parse_args() + +if len(args) < 1: + parser.print_usage() + sys.exit(1) + +url = args[0] +if (len(args) > 1): + objectclass = args[1] +else: + objectclass = None + +def uniq_list(alist): + """return a unique list""" + set = {} + return [set.setdefault(e,e) for e in alist if e not in set] + + +lp_ctx = sambaopts.get_loadparm() + +creds = credopts.get_credentials(lp_ctx) +db = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"]) + +# get the rootDSE +res = db.search(base="", expression="", + scope=ldb.SCOPE_BASE, + attrs=["schemaNamingContext"]) +rootDse = res[0] + +schema_base = rootDse["schemaNamingContext"][0] + +def possible_inferiors_search(db, oc): + """return the possible inferiors via a search for the possibleInferiors attribute""" + res = db.search(base=schema_base, + expression=("ldapDisplayName=%s" % oc), + attrs=["possibleInferiors"]) + + poss=[] + if len(res) == 0 or res[0].get("possibleInferiors") is None: + return poss + for item in res[0]["possibleInferiors"]: + poss.append(str(item)) + poss = uniq_list(poss) + poss.sort() + return poss; + + + +# see [MS-ADTS] section 3.1.1.4.5.21 +# and section 3.1.1.4.2 for this algorithm + +# !systemOnly=TRUE +# !objectClassCategory=2 +# !objectClassCategory=3 + +def SUPCLASSES(classinfo, oc): + list = [] + if oc == "top": + return list + if classinfo[oc].get("SUPCLASSES") is not None: + return classinfo[oc]["SUPCLASSES"] + res = classinfo[oc]["subClassOf"]; + for r in res: + list.append(r) + list.extend(SUPCLASSES(classinfo,r)) + classinfo[oc]["SUPCLASSES"] = list + return list + +def AUXCLASSES(classinfo, oclist): + list = [] + if oclist == []: + return list + for oc in oclist: + if classinfo[oc].get("AUXCLASSES") is not None: + list.extend(classinfo[oc]["AUXCLASSES"]) + else: + list2 = [] + list2.extend(classinfo[oc]["systemAuxiliaryClass"]) + list2.extend(AUXCLASSES(classinfo, classinfo[oc]["systemAuxiliaryClass"])) + list2.extend(classinfo[oc]["auxiliaryClass"]) + list2.extend(AUXCLASSES(classinfo, classinfo[oc]["auxiliaryClass"])) + list2.extend(AUXCLASSES(classinfo, SUPCLASSES(classinfo, oc))) + classinfo[oc]["AUXCLASSES"] = list2 + list.extend(list2) + return list + +def SUBCLASSES(classinfo, oclist): + list = [] + for oc in oclist: + list.extend(classinfo[oc]["SUBCLASSES"]) + return list + +def POSSSUPERIORS(classinfo, oclist): + list = [] + for oc in oclist: + if classinfo[oc].get("POSSSUPERIORS") is not None: + list.extend(classinfo[oc]["POSSSUPERIORS"]) + else: + list2 = [] + list2.extend(classinfo[oc]["systemPossSuperiors"]) + list2.extend(classinfo[oc]["possSuperiors"]) + list2.extend(POSSSUPERIORS(classinfo, SUPCLASSES(classinfo, oc))) + if opts.wspp: + # the WSPP docs suggest we should do this: + list2.extend(POSSSUPERIORS(classinfo, AUXCLASSES(classinfo, [oc]))) + else: + # but testing against w2k3 and w2k8 shows that we need to do this instead + list2.extend(SUBCLASSES(classinfo, list2)) + classinfo[oc]["POSSSUPERIORS"] = list2 + list.extend(list2) + return list + +def pull_classinfo(db): + """At startup we build a classinfo[] dictionary that holds all the information needed to construct the possible inferiors""" + classinfo = {} + res = db.search(base=schema_base, + expression="objectclass=classSchema", + attrs=["ldapDisplayName", "systemOnly", "objectClassCategory", + "possSuperiors", "systemPossSuperiors", + "auxiliaryClass", "systemAuxiliaryClass", "subClassOf"]) + for r in res: + name = str(r["ldapDisplayName"][0]) + classinfo[name] = {} + if str(r["systemOnly"]) == "TRUE": + classinfo[name]["systemOnly"] = True + else: + classinfo[name]["systemOnly"] = False + if r.get("objectClassCategory"): + classinfo[name]["objectClassCategory"] = int(r["objectClassCategory"][0]) + else: + classinfo[name]["objectClassCategory"] = 0 + for a in [ "possSuperiors", "systemPossSuperiors", + "auxiliaryClass", "systemAuxiliaryClass", + "subClassOf" ]: + classinfo[name][a] = [] + if r.get(a): + for i in r[a]: + classinfo[name][a].append(str(i)) + + # build a list of subclasses for each class + def subclasses_recurse(subclasses, oc): + list = subclasses[oc] + for c in list: + list.extend(subclasses_recurse(subclasses, c)) + return list + + subclasses = {} + for oc in classinfo: + subclasses[oc] = [] + for oc in classinfo: + for c in classinfo[oc]["subClassOf"]: + if not c == oc: + subclasses[c].append(oc) + for oc in classinfo: + classinfo[oc]["SUBCLASSES"] = uniq_list(subclasses_recurse(subclasses, oc)) + + return classinfo + +def is_in_list(list, c): + for a in list: + if c == a: + return True + return False + +def possible_inferiors_constructed(db, classinfo, c): + list = [] + for oc in classinfo: + superiors = POSSSUPERIORS(classinfo, [oc]) + if (is_in_list(superiors, c) and + classinfo[oc]["systemOnly"] == False and + classinfo[oc]["objectClassCategory"] != 2 and + classinfo[oc]["objectClassCategory"] != 3): + list.append(oc) + list = uniq_list(list) + list.sort() + return list + +def test_class(db, classinfo, oc): + """test to see if one objectclass returns the correct possibleInferiors""" + print "testing objectClass %s" % oc + poss1 = possible_inferiors_search(db, oc) + poss2 = possible_inferiors_constructed(db, classinfo, oc) + if poss1 != poss2: + print "Returned incorrect list for objectclass %s" % oc + print poss1 + print poss2 + for i in range(0,min(len(poss1),len(poss2))): + print "%30s %30s" % (poss1[i], poss2[i]) + exit(1) + +def get_object_classes(db): + """return a list of all object classes""" + list=[] + for item in classinfo: + list.append(item) + return list + +classinfo = pull_classinfo(db) + +if objectclass is None: + for oc in get_object_classes(db): + test_class(db,classinfo,oc) +else: + test_class(db,classinfo,objectclass) + +print "Lists match OK" diff --git a/source4/headermap.txt b/source4/headermap.txt index 280d60beb2..1c86f9e934 100644 --- a/source4/headermap.txt +++ b/source4/headermap.txt @@ -86,6 +86,8 @@ librpc/gen_ndr/nbt.h: gen_ndr/nbt.h librpc/gen_ndr/svcctl.h: gen_ndr/svcctl.h librpc/gen_ndr/ndr_svcctl.h: gen_ndr/ndr_svcctl.h librpc/gen_ndr/ndr_svcctl_c.h: gen_ndr/ndr_svcctl_c.h +../librpc/gen_ndr/dcerpc.h: gen_ndr/dcerpc.h +../librpc/gen_ndr/ndr_dcerpc.h: gen_ndr/ndr_dcerpc.h ../librpc/gen_ndr/netlogon.h: gen_ndr/netlogon.h ../librpc/gen_ndr/ndr_misc.h: gen_ndr/ndr_misc.h ../librpc/gen_ndr/mgmt.h: gen_ndr/mgmt.h diff --git a/source4/heimdal_build/replace.c b/source4/heimdal_build/replace.c index 41309fea6e..ba43dd9495 100644 --- a/source4/heimdal_build/replace.c +++ b/source4/heimdal_build/replace.c @@ -84,3 +84,7 @@ return -1; } #endif + +const char *heimdal_version = "samba-internal-heimdal"; +const char *heimdal_long_version = "samba-interal-heimdal"; + diff --git a/source4/heimdal_build/roken.h b/source4/heimdal_build/roken.h index 3edeb2fb2e..e3edd53872 100644 --- a/source4/heimdal_build/roken.h +++ b/source4/heimdal_build/roken.h @@ -41,6 +41,22 @@ #define HAVE_STRNDUP #endif +#ifndef HAVE_STRLCPY +#define HAVE_STRLCPY +#endif + +#ifndef HAVE_STRLCAT +#define HAVE_STRLCAT +#endif + +#ifndef HAVE_STRCASECMP +#define HAVE_STRCASECMP +#endif + +#ifndef HAVE_MKSTEMP +#define HAVE_MKSTEMP +#endif + #ifndef HAVE_SETENV #define HAVE_SETENV #endif @@ -84,4 +100,7 @@ #undef SOCKET_WRAPPER_REPLACE #include "heimdal/lib/roken/roken.h.in" +extern const char *heimdal_version; +extern const char *heimdal_long_version; + #endif diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index 1cfe9852f0..3d11441062 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -345,7 +345,7 @@ static bool kdc_process(struct kdc_server *kdc, } if (k5_reply.length) { *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length); - krb5_free_data_contents(kdc->smb_krb5_context->krb5_context, &k5_reply); + krb5_data_free(&k5_reply); } else { *reply = data_blob(NULL, 0); } diff --git a/source4/lib/ldb/modules/paged_searches.c b/source4/lib/ldb/modules/paged_searches.c index 01e77cb22c..c5430eb9bf 100644 --- a/source4/lib/ldb/modules/paged_searches.c +++ b/source4/lib/ldb/modules/paged_searches.c @@ -2,6 +2,7 @@ ldb database library Copyright (C) Simo Sorce 2005-2008 + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -52,23 +53,40 @@ struct ps_context { char **saved_referrals; int num_referrals; + + struct ldb_request *down_req; }; -static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares) +static int check_ps_continuation(struct ps_context *ac, struct ldb_request *req, struct ldb_reply *ares) { - struct ps_context *ac; - struct ldb_paged_control *rep_control, *req_control; + struct ldb_context *ldb; + struct ldb_control *rep_control, *req_control; + struct ldb_paged_control *paged_rep_control = NULL, *paged_req_control = NULL; + ldb = ldb_module_get_ctx(ac->module); - ac = talloc_get_type(req->context, struct ps_context); + rep_control = ldb_reply_get_control(ares, LDB_CONTROL_PAGED_RESULTS_OID); + if (rep_control) { + paged_rep_control = talloc_get_type(rep_control->data, struct ldb_paged_control); + } - /* look up our paged control */ - if (!ares->controls || strcmp(LDB_CONTROL_PAGED_RESULTS_OID, ares->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; + req_control = ldb_request_get_control(req, LDB_CONTROL_PAGED_RESULTS_OID); + paged_req_control = talloc_get_type(req_control->data, struct ldb_paged_control); + + if (!rep_control || !paged_rep_control) { + if (paged_req_control->cookie) { + /* something wrong here - why give us a control back befre, but not one now? */ + ldb_set_errstring(ldb, "paged_searches: ERROR: We got back a control from a previous page, but this time no control was returned!"); + return LDB_ERR_OPERATIONS_ERROR; + } else { + /* No cookie recived yet, valid to just return the full data set */ + + /* we are done */ + ac->pending = false; + return LDB_SUCCESS; + } } - rep_control = talloc_get_type(ares->controls[0]->data, struct ldb_paged_control); - if (rep_control->cookie_len == 0) { + if (paged_rep_control->cookie_len == 0) { /* we are done */ ac->pending = false; return LDB_SUCCESS; @@ -79,21 +97,14 @@ static int check_ps_continuation(struct ldb_request *req, struct ldb_reply *ares /* if there's a reply control we must find a request * control matching it */ - if (strcmp(LDB_CONTROL_PAGED_RESULTS_OID, req->controls[0]->oid) != 0) { - /* something wrong here */ - return LDB_ERR_OPERATIONS_ERROR; - } - - req_control = talloc_get_type(req->controls[0]->data, struct ldb_paged_control); - - if (req_control->cookie) { - talloc_free(req_control->cookie); + if (paged_req_control->cookie) { + talloc_free(paged_req_control->cookie); } - req_control->cookie = talloc_memdup(req_control, - rep_control->cookie, - rep_control->cookie_len); - req_control->cookie_len = rep_control->cookie_len; + paged_req_control->cookie = talloc_memdup(req_control, + paged_rep_control->cookie, + paged_rep_control->cookie_len); + paged_req_control->cookie_len = paged_rep_control->cookie_len; ac->pending = true; return LDB_SUCCESS; @@ -141,8 +152,6 @@ static int send_referrals(struct ps_context *ac) return LDB_SUCCESS; } -static int ps_next_request(struct ps_context *ac); - static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) { struct ps_context *ac; @@ -176,14 +185,15 @@ static int ps_callback(struct ldb_request *req, struct ldb_reply *ares) case LDB_REPLY_DONE: - ret = check_ps_continuation(req, ares); + ret = check_ps_continuation(ac, req, ares); if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); } if (ac->pending) { - ret = ps_next_request(ac); + ret = ldb_next_request(ac->module, ac->down_req); + if (ret != LDB_SUCCESS) { return ldb_module_done(ac->req, NULL, NULL, ret); @@ -214,14 +224,16 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req) struct ldb_context *ldb; struct private_data *private_data; struct ps_context *ac; + struct ldb_paged_control *control; + int ret; private_data = talloc_get_type(ldb_module_get_private(module), struct private_data); ldb = ldb_module_get_ctx(module); - /* check if paging is supported and if there is a any control */ - if (!private_data || !private_data->paged_supported || req->controls) { + /* check if paging is supported */ + if (!private_data || !private_data->paged_supported) { /* do not touch this request paged controls not - * supported or explicit controls have been set or we + * supported or we * are just not setup yet */ return ldb_next_request(module, req); } @@ -238,30 +250,9 @@ static int ps_search(struct ldb_module *module, struct ldb_request *req) ac->saved_referrals = NULL; ac->num_referrals = 0; - return ps_next_request(ac); -} - -static int ps_next_request(struct ps_context *ac) { - - struct ldb_context *ldb; - struct ldb_paged_control *control; - struct ldb_control **controls; - struct ldb_request *new_req; - int ret; - ldb = ldb_module_get_ctx(ac->module); - controls = talloc_array(ac, struct ldb_control *, 2); - if (!controls) { - return LDB_ERR_OPERATIONS_ERROR; - } - - controls[0] = talloc(controls, struct ldb_control); - if (!controls[0]) { - return LDB_ERR_OPERATIONS_ERROR; - } - - control = talloc(controls[0], struct ldb_paged_control); + control = talloc(ac, struct ldb_paged_control); if (!control) { return LDB_ERR_OPERATIONS_ERROR; } @@ -270,26 +261,28 @@ static int ps_next_request(struct ps_context *ac) { control->cookie = NULL; control->cookie_len = 0; - controls[0]->oid = LDB_CONTROL_PAGED_RESULTS_OID; - controls[0]->critical = 1; - controls[0]->data = control; - controls[1] = NULL; - - ret = ldb_build_search_req_ex(&new_req, ldb, ac, + ret = ldb_build_search_req_ex(&ac->down_req, ldb, ac, ac->req->op.search.base, ac->req->op.search.scope, ac->req->op.search.tree, ac->req->op.search.attrs, - controls, + ac->req->controls, ac, ps_callback, ac->req); if (ret != LDB_SUCCESS) { return ret; } - talloc_steal(new_req, controls); - return ldb_next_request(ac->module, new_req); + ret = ldb_request_add_control(ac->down_req, LDB_CONTROL_PAGED_RESULTS_OID, + true, control); + if (ret != LDB_SUCCESS) { + return ret; + } + + talloc_steal(ac->down_req, control); + + return ldb_next_request(ac->module, ac->down_req); } static int check_supported_paged(struct ldb_request *req, diff --git a/source4/lib/ldb/pyldb.c b/source4/lib/ldb/pyldb.c index 7ff4bf4aad..bceda05e4f 100644 --- a/source4/lib/ldb/pyldb.c +++ b/source4/lib/ldb/pyldb.c @@ -5,7 +5,7 @@ Copyright (C) 2005,2006 Tim Potter <tpot@samba.org> Copyright (C) 2006 Simo Sorce <idra@samba.org> - Copyright (C) 2007-2008 Jelmer Vernooij <jelmer@samba.org> + Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org> ** NOTE! The following LGPL license applies to the ldb ** library. This does NOT imply that all of Samba is released @@ -65,18 +65,7 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, PyObject *ret; new_val = *val; - - if (ldb_ctx != NULL) { - a = ldb_schema_attribute_by_name(ldb_ctx, el->name); - - if (a != NULL) { - if (a->syntax->ldif_write_fn(ldb_ctx, mem_ctx, val, &new_val) != 0) { - talloc_free(mem_ctx); - return NULL; - } - } - } - + ret = PyString_FromStringAndSize((const char *)new_val.data, new_val.length); talloc_free(mem_ctx); @@ -84,6 +73,14 @@ static PyObject *PyObject_FromLdbValue(struct ldb_context *ldb_ctx, return ret; } +/** + * Obtain a ldb DN from a Python object. + * + * @param mem_ctx Memory context + * @param object Python object + * @param ldb_ctx LDB context + * @return Whether or not the conversion succeeded + */ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, struct ldb_context *ldb_ctx, struct ldb_dn **dn) { @@ -104,6 +101,12 @@ bool PyObject_AsDn(TALLOC_CTX *mem_ctx, PyObject *object, return false; } +/** + * Create a Python object from a ldb_result. + * + * @param result LDB result to convert + * @return Python object with converted result (a list object) + */ static PyObject *PyLdbResult_FromResult(struct ldb_result *result) { PyObject *ret; @@ -119,7 +122,16 @@ static PyObject *PyLdbResult_FromResult(struct ldb_result *result) return ret; } -static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, PyObject *obj) +/** + * Create a LDB Result from a Python object. + * If conversion fails, NULL will be returned and a Python exception set. + * + * @param mem_ctx Memory context in which to allocate the LDB Result + * @param obj Python object to convert + * @return a ldb_result, or NULL if the conversion failed + */ +static struct ldb_result *PyLdbResult_AsResult(TALLOC_CTX *mem_ctx, + PyObject *obj) { struct ldb_result *res; int i; @@ -451,7 +463,6 @@ static PyObject *py_ldb_get_schema_basedn(PyLdbObject *self) return PyLdbDn_FromDn(dn); } - static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) { struct ldb_dn *dn = ldb_get_config_basedn(PyLdb_AsLdbContext(self)); @@ -460,7 +471,6 @@ static PyObject *py_ldb_get_config_basedn(PyLdbObject *self) return PyLdbDn_FromDn(dn); } - static PyObject *py_ldb_get_default_basedn(PyLdbObject *self) { struct ldb_dn *dn = ldb_get_default_basedn(PyLdb_AsLdbContext(self)); @@ -652,8 +662,6 @@ static PyObject *py_ldb_add(PyLdbObject *self, PyObject *args) Py_RETURN_NONE; } - - static PyObject *py_ldb_delete(PyLdbObject *self, PyObject *args) { PyObject *py_dn; @@ -1257,6 +1265,21 @@ PyTypeObject PyLdbModule = { .tp_flags = Py_TPFLAGS_DEFAULT, }; + +/** + * Create a ldb_message_element from a Python object. + * + * This will accept any sequence objects that contains strings, or + * a string object. + * + * A reference to set_obj will be borrowed. + * + * @param mem_ctx Memory context + * @param set_obj Python object to convert + * @param flags ldb_message_element flags to set + * @param attr_name Name of the attribute + * @return New ldb_message_element, allocated as child of mem_ctx + */ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, PyObject *set_obj, int flags, const char *attr_name) @@ -1274,9 +1297,7 @@ struct ldb_message_element *PyObject_AsMessageElement(TALLOC_CTX *mem_ctx, me->num_values = 1; me->values = talloc_array(me, struct ldb_val, me->num_values); me->values[0].length = PyString_Size(set_obj); - me->values[0].data = (uint8_t *)talloc_strndup(me->values, - PyString_AsString(set_obj), - me->values[0].length); + me->values[0].data = (uint8_t *)PyString_AsString(set_obj); } else if (PySequence_Check(set_obj)) { int i; me->num_values = PySequence_Size(set_obj); diff --git a/source4/lib/ldb/tests/python/api.py b/source4/lib/ldb/tests/python/api.py index c372b8fa71..07500e2372 100755 --- a/source4/lib/ldb/tests/python/api.py +++ b/source4/lib/ldb/tests/python/api.py @@ -258,6 +258,19 @@ class SimpleLdb(unittest.TestCase): l = ldb.Ldb(filename()) l.set_debug(my_report_fn) + def test_zero_byte_string(self): + """Testing we do not get trapped in the \0 byte in a property string.""" + l = ldb.Ldb(filename()) + l.add({ + "dn" : "dc=somedn", + "objectclass" : "user", + "cN" : "LDAPtestUSER", + "givenname" : "ldap", + "displayname" : "foo\0bar", + }) + res = l.search(expression="(dn=dc=somedn)") + self.assertEquals("foo\0bar", res[0]["displayname"][0]) + class DnTests(unittest.TestCase): def setUp(self): diff --git a/source4/lib/smbreadline/smbreadline.c b/source4/lib/smbreadline/smbreadline.c index 5fb3bf4fae..b07417357f 100644 --- a/source4/lib/smbreadline/smbreadline.c +++ b/source4/lib/smbreadline/smbreadline.c @@ -83,6 +83,7 @@ static char *smb_readline_replacement(const char *prompt, void (*callback)(void) char *ret; printf("%s", prompt); + fflush(stdout); line = (char *)malloc(BUFSIZ); if (!line) { diff --git a/source4/libcli/raw/interfaces.h b/source4/libcli/raw/interfaces.h index a0584c0aa4..bd93fa1695 100644 --- a/source4/libcli/raw/interfaces.h +++ b/source4/libcli/raw/interfaces.h @@ -53,6 +53,16 @@ struct smb2_handle { uint64_t data[2]; }; +/* + SMB2 lease structure (per MS-SMB2 2.2.13) +*/ +struct smb2_lease { + uint64_t lease_key[2]; + uint32_t lease_state; + uint32_t lease_flags; /* should be 0 */ + uint64_t lease_duration; /* should be 0 */ +}; + struct ntvfs_handle; /* @@ -1633,6 +1643,7 @@ union smb_open { bool query_maximal_access; NTTIME timewarp; bool query_on_disk_id; + struct smb2_lease *lease_request; /* and any additional blobs the caller wants */ struct smb2_create_blobs { @@ -1666,6 +1677,7 @@ union smb_open { /* optional return values matching tagged values in the call */ uint32_t maximal_access; uint8_t on_disk_id[32]; + struct smb2_lease lease_response; /* tagged blobs in the reply */ struct smb2_create_blobs blobs; diff --git a/source4/libcli/security/config.mk b/source4/libcli/security/config.mk index d6d9ad5545..9d23fe9588 100644 --- a/source4/libcli/security/config.mk +++ b/source4/libcli/security/config.mk @@ -4,7 +4,5 @@ PUBLIC_DEPENDENCIES = LIBNDR LIBSECURITY_COMMON LIBSECURITY_OBJ_FILES = $(addprefix $(libclisrcdir)/security/, \ security_token.o security_descriptor.o \ access_check.o privilege.o sddl.o) \ - ../libcli/security/secace.o \ - ../libcli/security/secacl.o $(eval $(call proto_header_template,$(libclisrcdir)/security/proto.h,$(LIBSECURITY_OBJ_FILES:.o=.c))) diff --git a/source4/libcli/smb2/create.c b/source4/libcli/smb2/create.c index 8a40e56a00..344be60f6e 100644 --- a/source4/libcli/smb2/create.c +++ b/source4/libcli/smb2/create.c @@ -312,6 +312,23 @@ struct smb2_request *smb2_create_send(struct smb2_tree *tree, struct smb2_create } } + if (io->in.lease_request) { + uint8_t data[32]; + + memcpy(&data[0], io->in.lease_request->lease_key, 16); + SIVAL(data, 16, io->in.lease_request->lease_state); + SIVAL(data, 20, io->in.lease_request->lease_flags); + SBVAL(data, 24, io->in.lease_request->lease_duration); + + status = smb2_create_blob_add(req, &blobs, + SMB2_CREATE_TAG_RQLS, + data_blob_const(data, 32)); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(req); + return NULL; + } + } + /* and any custom blobs */ for (i=0;i<io->in.blobs.num_blobs;i++) { status = smb2_create_blob_add(req, &blobs, @@ -402,6 +419,19 @@ NTSTATUS smb2_create_recv(struct smb2_request *req, TALLOC_CTX *mem_ctx, struct } memcpy(io->out.on_disk_id, io->out.blobs.blobs[i].data.data, 32); } + if (strcmp(io->out.blobs.blobs[i].tag, SMB2_CREATE_TAG_RQLS) == 0) { + uint8_t *data; + if (io->out.blobs.blobs[i].data.length != 32) { + smb2_request_destroy(req); + return NT_STATUS_INVALID_NETWORK_RESPONSE; + } + + data = io->out.blobs.blobs[i].data.data; + memcpy(io->out.lease_response.lease_key, data, 16); + io->out.lease_response.lease_state = IVAL(data, 16); + io->out.lease_response.lease_flags = IVAL(data, 20); + io->out.lease_response.lease_duration = BVAL(data, 24); + } } data_blob_free(&blob); diff --git a/source4/libcli/smb2/smb2.h b/source4/libcli/smb2/smb2.h index 7c07c84740..fd961ce5f3 100644 --- a/source4/libcli/smb2/smb2.h +++ b/source4/libcli/smb2/smb2.h @@ -263,6 +263,13 @@ struct smb2_request { #define SMB2_OPLOCK_LEVEL_II 0x01 #define SMB2_OPLOCK_LEVEL_EXCLUSIVE 0x08 #define SMB2_OPLOCK_LEVEL_BATCH 0x09 +#define SMB2_OPLOCK_LEVEL_LEASE 0xFF + +/* SMB2 lease bits */ +#define SMB2_LEASE_NONE 0x00 +#define SMB2_LEASE_READ 0x01 +#define SMB2_LEASE_HANDLE 0x02 +#define SMB2_LEASE_WRITE 0x04 /* SMB2 impersonation levels */ #define SMB2_IMPERSONATION_ANONYMOUS 0x00 @@ -279,6 +286,7 @@ struct smb2_request { #define SMB2_CREATE_TAG_ALSI "AlSi" #define SMB2_CREATE_TAG_TWRP "TWrp" #define SMB2_CREATE_TAG_QFID "QFid" +#define SMB2_CREATE_TAG_RQLS "RqLs" /* SMB2 Create ignore some more create_options */ #define SMB2_CREATE_OPTIONS_NOT_SUPPORTED_MASK (NTCREATEX_OPTIONS_TREE_CONNECTION | \ diff --git a/source4/librpc/config.mk b/source4/librpc/config.mk index 2f1b14dc37..64a4750ab7 100644 --- a/source4/librpc/config.mk +++ b/source4/librpc/config.mk @@ -595,9 +595,9 @@ RPC_NDR_KEYSVC_OBJ_FILES = ../librpc/gen_ndr/ndr_keysvc_c.o [SUBSYSTEM::NDR_DCERPC] PUBLIC_DEPENDENCIES = LIBNDR -NDR_DCERPC_OBJ_FILES = $(gen_ndrsrcdir)/ndr_dcerpc.o +NDR_DCERPC_OBJ_FILES = ../librpc/gen_ndr/ndr_dcerpc.o -PUBLIC_HEADERS += $(addprefix $(librpcsrcdir)/, gen_ndr/dcerpc.h gen_ndr/ndr_dcerpc.h) +PUBLIC_HEADERS += ../librpc/gen_ndr/dcerpc.h ../librpc/gen_ndr/ndr_dcerpc.h ################################################ # Start SUBSYSTEM dcerpc diff --git a/source4/main.mk b/source4/main.mk index a143604f33..d7db0580e9 100644 --- a/source4/main.mk +++ b/source4/main.mk @@ -46,6 +46,7 @@ mkinclude torture/config.mk mkinclude librpc/config.mk mkinclude client/config.mk mkinclude libcli/config.mk +mkinclude ../libcli/cldap/config.mk mkinclude scripting/python/config.mk mkinclude kdc/config.mk mkinclude ../lib/smbconf/config.mk diff --git a/source4/min_versions.m4 b/source4/min_versions.m4 index eaefbd5148..1dd3501b99 100644 --- a/source4/min_versions.m4 +++ b/source4/min_versions.m4 @@ -1,6 +1,6 @@ # Minimum and exact required versions for various libraries # if we use the ones installed in the system. -TDB_MIN_VERSION=1.1.3 -TALLOC_MIN_VERSION=1.3.0 -LDB_REQUIRED_VERSION=0.9.3 -TEVENT_REQUIRED_VERSION=0.9.5 +define(TDB_MIN_VERSION,1.1.3) +define(TALLOC_MIN_VERSION,1.3.0) +define(LDB_REQUIRED_VERSION,0.9.3) +define(TEVENT_REQUIRED_VERSION,0.9.5) diff --git a/source4/script/uninstallman.sh b/source4/script/uninstallman.sh index 9b087c68bb..edc1c47e4d 100755 --- a/source4/script/uninstallman.sh +++ b/source4/script/uninstallman.sh @@ -8,7 +8,7 @@ MANPAGES=$* for I in $MANPAGES do - SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/" + SECTION=`echo -n $I | sed "s/.*\(.\)$/\1/"` FNAME=$MANDIR/man$SECTION/$I if test -f $FNAME; then echo Deleting $FNAME diff --git a/source4/scripting/bin/fullschema b/source4/scripting/bin/fullschema new file mode 100644 index 0000000000..41c45f30c8 --- /dev/null +++ b/source4/scripting/bin/fullschema @@ -0,0 +1,179 @@ +#!/usr/bin/python +# +# work out the minimal schema for a set of objectclasses +# + +import base64 +import optparse +import os +import sys + +# Find right directory when running from source tree +sys.path.insert(0, "bin/python") + +import samba +from samba import getopt as options, Ldb +from ldb import SCOPE_SUBTREE, SCOPE_BASE, LdbError +import sys + +parser = optparse.OptionParser("fullschema <URL>") +sambaopts = options.SambaOptions(parser) +parser.add_option_group(sambaopts) +credopts = options.CredentialsOptions(parser) +parser.add_option_group(credopts) +parser.add_option_group(options.VersionOptions(parser)) +parser.add_option("--dump-classes", action="store_true") +parser.add_option("--dump-attributes", action="store_true") + +opts, args = parser.parse_args() +opts.dump_all = True + +if opts.dump_classes: + opts.dump_all = False +if opts.dump_attributes: + opts.dump_all = False +if opts.dump_all: + opts.dump_classes = True + opts.dump_attributes = True + +if len(args) != 1: + parser.print_usage() + sys.exit(1) + +url = args[0] + +lp_ctx = sambaopts.get_loadparm() + +creds = credopts.get_credentials(lp_ctx) +ldb = Ldb(url, credentials=creds, lp=lp_ctx, options=["modules:paged_searches"]) + +# the attributes we need for objectclasses +class_attrs = ["objectClass", + "cn", + "subClassOf", + "governsID", + "possSuperiors", + "possibleInferiors", + "mayContain", + "mustContain", + "auxiliaryClass", + "rDNAttID", + "adminDisplayName", + "adminDescription", + "objectClassCategory", + "lDAPDisplayName", + "schemaIDGUID", + "systemOnly", + "systemPossSuperiors", + "systemMayContain", + "systemMustContain", + "systemAuxiliaryClass", + "defaultSecurityDescriptor", + "systemFlags", + "defaultHidingValue", + "defaultObjectCategory", + + # this attributes are not used by w2k3 + "schemaFlagsEx", + "msDs-IntId", + "msDs-Schema-Extensions", + "classDisplayName", + "isDefunct"] + +attrib_attrs = ["objectClass", + "cn", + "attributeID", + "attributeSyntax", + "isSingleValued", + "rangeLower", + "rangeUpper", + "mAPIID", + "linkID", + "adminDisplayName", + "oMObjectClass", + "adminDescription", + "oMSyntax", + "searchFlags", + "extendedCharsAllowed", + "lDAPDisplayName", + "schemaIDGUID", + "attributeSecurityGUID", + "systemOnly", + "systemFlags", + "isMemberOfPartialAttributeSet", + + # this attributes are not used by w2k3 + "schemaFlagsEx", + "msDs-IntId", + "msDs-Schema-Extensions", + "classDisplayName", + "isEphemeral", + "isDefunct"] + +class Objectclass(dict): + + def __init__(self, ldb, name): + """create an objectclass object""" + self.name = name + + +class Attribute(dict): + + def __init__(self, ldb, name): + """create an attribute object""" + self.name = name + self["cn"] = get_object_cn(ldb, name) + + + +def fix_dn(dn): + """fix a string DN to use ${SCHEMADN}""" + return dn.replace(rootDse["schemaNamingContext"][0], "${SCHEMADN}") + + +def write_ldif_one(o, attrs): + """dump an object as ldif""" + print "dn: CN=%s,${SCHEMADN}" % o["cn"] + for a in attrs: + if not o.has_key(a): + continue + # special case for oMObjectClass, which is a binary object + v = o[a] + for j in v: + value = fix_dn(j) + if a != "cn": + if a == "oMObjectClass": + print "%s:: %s" % (a, base64.b64encode(value)) + elif a.endswith("GUID"): + print "%s: %s" % (a, ldb.schema_format_value(a, value)) + else: + print "%s: %s" % (a, value) + print "" + + +# get the rootDSE +res = ldb.search(base="", expression="", scope=SCOPE_BASE, attrs=["schemaNamingContext"]) +rootDse = res[0] + +if opts.dump_attributes: + res = ldb.search(expression="objectClass=attributeSchema", + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=attrib_attrs, + controls=["server_sort:1:0:cn"]) + + for msg in res: + o = Objectclass(ldb, msg["ldapDisplayName"]) + for a in msg: + o[a] = msg[a] + write_ldif_one(o, attrib_attrs) + +if opts.dump_classes: + res = ldb.search(expression="objectClass=classSchema", + base=rootDse["schemaNamingContext"][0], scope=SCOPE_SUBTREE,attrs=class_attrs, + controls=["server_sort:1:0:cn"]) + + for msg in res: + o = Objectclass(ldb, msg["ldapDisplayName"]) + for a in msg: + o[a] = msg[a] + write_ldif_one(o, class_attrs) + diff --git a/source4/scripting/bin/minschema b/source4/scripting/bin/minschema index f2dfdcb564..c860495e96 100755 --- a/source4/scripting/bin/minschema +++ b/source4/scripting/bin/minschema @@ -72,7 +72,6 @@ class_attrs = ["objectClass", "mustContain", "auxiliaryClass", "rDNAttID", - "showInAdvancedViewOnly", "adminDisplayName", "adminDescription", "objectClassCategory", @@ -104,7 +103,6 @@ attrib_attrs = ["objectClass", "rangeUpper", "mAPIID", "linkID", - "showInAdvancedViewOnly", "adminDisplayName", "oMObjectClass", "adminDescription", @@ -405,40 +403,40 @@ def attribute_list(objectclass, attr1, attr2): def aggregate_list(name, list): """write out a list in aggregate form""" - if list is None: - return - print "%s ( %s )" % (name, "$ ".join(list)) + if list == []: + return "" + return " %s ( %s )" % (name, " $ ".join(list)) def write_aggregate_objectclass(objectclass): """write the aggregate record for an objectclass""" - print "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name), + line = "objectClasses: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name) if not objectclass.has_key('subClassOf'): - print "SUP %s " % objectclass['subClassOf'], + line += "SUP %s" % objectclass['subClassOf'] if objectclass["objectClassCategory"] == 1: - print "STRUCTURAL ", + line += "STRUCTURAL" elif objectclass["objectClassCategory"] == 2: - print "ABSTRACT ", + line += "ABSTRACT" elif objectclass["objectClassCategory"] == 3: - print "AUXILIARY ", + line += "AUXILIARY" list = attribute_list(objectclass, "systemMustContain", "mustContain") - aggregate_list("MUST", list) + line += aggregate_list("MUST", list) list = attribute_list(objectclass, "systemMayContain", "mayContain") - aggregate_list("MAY", list) + line += aggregate_list("MAY", list) - print ")" + print line + " )" def write_aggregate_ditcontentrule(objectclass): """write the aggregate record for an ditcontentrule""" list = attribute_list(objectclass, "auxiliaryClass", "systemAuxiliaryClass") - if list is None: + if list == []: return - print "dITContentRules: ( %s NAME '%s' " % (objectclass["governsID"], objectclass.name) + line = "dITContentRules: ( %s NAME '%s'" % (objectclass["governsID"], objectclass.name) - aggregate_list("AUX", list) + line += aggregate_list("AUX", list) may_list = [] must_list = [] @@ -451,31 +449,30 @@ def write_aggregate_ditcontentrule(objectclass): "mustContain", "systemMustContain") must_list = must_list + list2 - aggregate_list("MUST", must_list) - aggregate_list("MAY", may_list) + line += aggregate_list("MUST", must_list) + line += aggregate_list("MAY", may_list) - print ")\n" + print line + " )" def write_aggregate_attribute(attrib): """write the aggregate record for an attribute""" - print "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % ( + line = "attributeTypes: ( %s NAME '%s' SYNTAX '%s' " % ( attrib["attributeID"], attrib.name, map_attribute_syntax(attrib["attributeSyntax"])) if attrib.get('isSingleValued') == "TRUE": - print "SINGLE-VALUE " + line += "SINGLE-VALUE " if attrib.get('systemOnly') == "TRUE": - print "NO-USER-MODIFICATION " + line += "NO-USER-MODIFICATION " - print ")\n" + print line + ")" def write_aggregate(): """write the aggregate record""" - print "dn: CN=Aggregate,${SCHEMADN}\n" + print "dn: CN=Aggregate,${SCHEMADN}" print """objectClass: top objectClass: subSchema -objectCategory: CN=SubSchema,${SCHEMADN} -""" +objectCategory: CN=SubSchema,${SCHEMADN}""" if not opts.dump_subschema_auto: return diff --git a/source4/scripting/python/samba/__init__.py b/source4/scripting/python/samba/__init__.py index a49e6e1ead..c5827b96e0 100644 --- a/source4/scripting/python/samba/__init__.py +++ b/source4/scripting/python/samba/__init__.py @@ -54,7 +54,7 @@ class Ldb(ldb.Ldb): functions see samdb.py. """ def __init__(self, url=None, session_info=None, credentials=None, - modules_dir=None, lp=None): + modules_dir=None, lp=None, options=None): """Open a Samba Ldb file. :param url: Optional LDB URL to open @@ -67,7 +67,7 @@ class Ldb(ldb.Ldb): modules-dir is used by default and that credentials and session_info can be passed through (required by some modules). """ - super(Ldb, self).__init__() + super(Ldb, self).__init__(options=options) if modules_dir is not None: self.set_modules_dir(modules_dir) @@ -90,7 +90,7 @@ class Ldb(ldb.Ldb): #self.set_debug(msg) if url is not None: - self.connect(url) + self.connect(url, options=options) def set_credentials(self, credentials): glue.ldb_set_credentials(self, credentials) diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 1e34b11d0a..64908ccb4d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1051,7 +1051,7 @@ def provision(setup_dir, message, session_info, serverrole=serverrole, ldap_backend=ldap_backend, ldap_backend_type=ldap_backend_type) - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": if paths.netlogon is None: message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.") message("Please either remove %s or see the template at %s" % diff --git a/source4/selftest/config.mk b/source4/selftest/config.mk index 324532c22a..1838a0bb38 100644 --- a/source4/selftest/config.mk +++ b/source4/selftest/config.mk @@ -59,31 +59,31 @@ test-%:: valgrindtest:: valgrindtest-all valgrindtest-quick:: all - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ $(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) valgrindtest-all:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) valgrindtest-env:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/valgrind_run $(LD_LIBPATH_OVERRIDE)" \ VALGRIND="valgrind -q --num-callers=30 --log-file=${selftest_prefix}/valgrind.log" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv gdbtest:: gdbtest-all gdbtest-quick:: all - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST) $(SELFTEST_QUICK_OPTS) --immediate --socket-wrapper $(TESTS) gdbtest-all:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --immediate --socket-wrapper $(TESTS) gdbtest-env:: everything - SMBD_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ + SAMBA_VALGRIND="xterm -n server -e $(selftestdir)/gdb_run $(LD_LIBPATH_OVERRIDE)" \ $(SELFTEST) $(SELFTEST_NOSLOW_OPTS) --socket-wrapper --testenv diff --git a/source4/smbd/server.c b/source4/smbd/server.c index d576782ab1..635e84fafe 100644 --- a/source4/smbd/server.c +++ b/source4/smbd/server.c @@ -365,5 +365,5 @@ static int binary_smbd_main(const char *binary_name, int argc, const char *argv[ int main(int argc, const char *argv[]) { - return binary_smbd_main("smbd", argc, argv); + return binary_smbd_main("samba", argc, argv); } diff --git a/source4/torture/ldap/cldap.c b/source4/torture/ldap/cldap.c index 98669288a8..814c9ac86d 100644 --- a/source4/torture/ldap/cldap.c +++ b/source4/torture/ldap/cldap.c @@ -59,8 +59,8 @@ static bool test_cldap_netlogon(struct torture_context *tctx, const char *dest) CHECK_STATUS(status, NT_STATUS_OK); ZERO_STRUCT(search); - search.in.dest_address = NULL;//dest; - search.in.dest_port = 0;//lp_cldap_port(tctx->lp_ctx); + search.in.dest_address = NULL; + search.in.dest_port = 0; search.in.acct_control = -1; search.in.version = NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX; search.in.map_response = true; diff --git a/source4/torture/smb2/config.mk b/source4/torture/smb2/config.mk index e0fc29f278..70b1743929 100644 --- a/source4/torture/smb2/config.mk +++ b/source4/torture/smb2/config.mk @@ -20,8 +20,9 @@ TORTURE_SMB2_OBJ_FILES = $(addprefix $(torturesrcdir)/smb2/, \ lock.o \ notify.o \ smb2.o \ - persistent_handles.o \ + durable_open.o \ oplocks.o \ + lease.o \ create.o \ read.o) diff --git a/source4/torture/smb2/persistent_handles.c b/source4/torture/smb2/durable_open.c index 05c5dbbe85..9cc25e3408 100644 --- a/source4/torture/smb2/persistent_handles.c +++ b/source4/torture/smb2/durable_open.c @@ -1,7 +1,7 @@ /* Unix SMB/CIFS implementation. - test suite for SMB2 persistent file handles + test suite for SMB2 durable opens Copyright (C) Stefan Metzmacher 2008 @@ -41,19 +41,19 @@ goto done; \ }} while (0) -/* - basic testing of SMB2 persistent file handles +/* + basic testing of SMB2 durable opens regarding the position information on the handle */ -bool torture_smb2_persistent_handles1(struct torture_context *tctx, - struct smb2_tree *tree1, - struct smb2_tree *tree2) +bool test_durable_open_file_position(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) { TALLOC_CTX *mem_ctx = talloc_new(tctx); struct smb2_handle h1, h2; struct smb2_create io1, io2; NTSTATUS status; - const char *fname = "persistent_handles.dat"; + const char *fname = "durable_open_position.dat"; DATA_BLOB b; union smb_fileinfo qfinfo; union smb_setfileinfo sfinfo; @@ -181,3 +181,122 @@ bool torture_smb2_persistent_handles1(struct torture_context *tctx, done: return ret; } + +/* + Open, disconnect, oplock break, reconnect. +*/ +bool test_durable_open_oplock(struct torture_context *tctx, + struct smb2_tree *tree1, + struct smb2_tree *tree2) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io1, io2; + struct smb2_handle h1; + NTSTATUS status; + const char *fname = "durable_open_oplock.dat"; + DATA_BLOB b; + bool ret = true; + + /* Clean slate */ + smb2_util_unlink(tree1, fname); + + /* Create with batch oplock */ + ZERO_STRUCT(io1); + io1.in.security_flags = 0x00; + io1.in.oplock_level = SMB2_OPLOCK_LEVEL_BATCH; + io1.in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION; + io1.in.create_flags = 0x00000000; + io1.in.reserved = 0x00000000; + io1.in.desired_access = SEC_RIGHTS_FILE_ALL; + io1.in.file_attributes = FILE_ATTRIBUTE_NORMAL; + io1.in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + io1.in.create_disposition = NTCREATEX_DISP_OPEN_IF; + io1.in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY | + NTCREATEX_OPTIONS_ASYNC_ALERT | + NTCREATEX_OPTIONS_NON_DIRECTORY_FILE | + 0x00200000; + io1.in.fname = fname; + + io2 = io1; + io2.in.create_disposition = NTCREATEX_DISP_OPEN; + + b = data_blob_talloc(mem_ctx, NULL, 16); + SBVAL(b.data, 0, 0); + SBVAL(b.data, 8, 0); + + status = smb2_create_blob_add(tree1, &io1.in.blobs, + SMB2_CREATE_TAG_DHNQ, + b); + CHECK_STATUS(status, NT_STATUS_OK); + + status = smb2_create(tree1, mem_ctx, &io1); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(io1.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); + CHECK_VAL(io1.out.create_action, NTCREATEX_ACTION_CREATED); + CHECK_VAL(io1.out.alloc_size, 0); + CHECK_VAL(io1.out.size, 0); + CHECK_VAL(io1.out.file_attr, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io1.out.reserved2, 0); + + h1 = io1.out.file.handle; + + /* Disconnect after getting the batch */ + talloc_free(tree1); + tree1 = NULL; + + /* + * Windows7 (build 7000) will break a batch oplock immediately if the + * original client is gone. (ZML: This seems like a bug. It should give + * some time for the client to reconnect!) + */ + status = smb2_create(tree2, mem_ctx, &io2); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_VAL(io2.out.oplock_level, SMB2_OPLOCK_LEVEL_BATCH); + CHECK_VAL(io2.out.create_action, NTCREATEX_ACTION_EXISTED); + CHECK_VAL(io2.out.alloc_size, 0); + CHECK_VAL(io2.out.size, 0); + CHECK_VAL(io2.out.file_attr, FILE_ATTRIBUTE_ARCHIVE); + CHECK_VAL(io2.out.reserved2, 0); + + /* What if tree1 tries to come back and reclaim? */ + if (!torture_smb2_connection(tctx, &tree1)) { + torture_warning(tctx, "couldn't reconnect, bailing\n"); + ret = false; + goto done; + } + + ZERO_STRUCT(io2); + io2.in.fname = fname; + + b = data_blob_talloc(tctx, NULL, 16); + SBVAL(b.data, 0, h1.data[0]); + SBVAL(b.data, 8, h1.data[1]); + + status = smb2_create_blob_add(tree2, &io2.in.blobs, + SMB2_CREATE_TAG_DHNC, + b); + CHECK_STATUS(status, NT_STATUS_OK); + + status = smb2_create(tree2, mem_ctx, &io2); + CHECK_STATUS(status, NT_STATUS_OBJECT_NAME_NOT_FOUND); + +done: + return ret; + +} + +struct torture_suite *torture_smb2_durable_open_init(void) +{ + struct torture_suite *suite = + torture_suite_create(talloc_autofree_context(), "DURABLE-OPEN"); + + torture_suite_add_2smb2_test(suite, "FILE-POSITION", + test_durable_open_file_position); + torture_suite_add_2smb2_test(suite, "OPLOCK", test_durable_open_oplock); + + suite->description = talloc_strdup(suite, "SMB2-DURABLE-OPEN tests"); + + return suite; +} diff --git a/source4/torture/smb2/lease.c b/source4/torture/smb2/lease.c new file mode 100644 index 0000000000..e67517324b --- /dev/null +++ b/source4/torture/smb2/lease.c @@ -0,0 +1,296 @@ +/* + Unix SMB/CIFS implementation. + + test suite for SMB2 leases + + Copyright (C) Zachary Loafman 2009 + + 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/security.h" +#include "libcli/smb2/smb2.h" +#include "libcli/smb2/smb2_calls.h" +#include "torture/torture.h" +#include "torture/smb2/proto.h" + +#define CHECK_VAL(v, correct) do { \ + if ((v) != (correct)) { \ + torture_result(tctx, TORTURE_FAIL, "(%s): wrong value for %s got 0x%x - should be 0x%x\n", \ + __location__, #v, (int)v, (int)correct); \ + ret = false; \ + }} while (0) + +#define CHECK_STATUS(status, correct) do { \ + if (!NT_STATUS_EQUAL(status, correct)) { \ + torture_result(tctx, TORTURE_FAIL, __location__": Incorrect status %s - should be %s", \ + nt_errstr(status), nt_errstr(correct)); \ + ret = false; \ + goto done; \ + }} while (0) + +static void smb2_lease_create(struct smb2_create *io, struct smb2_lease *ls, + bool dir, const char *name, uint64_t leasekey, + uint32_t leasestate) +{ + ZERO_STRUCT(*io); + io->in.security_flags = 0x00; + io->in.oplock_level = SMB2_OPLOCK_LEVEL_LEASE; + io->in.impersonation_level = NTCREATEX_IMPERSONATION_IMPERSONATION; + io->in.create_flags = 0x00000000; + io->in.reserved = 0x00000000; + io->in.desired_access = SEC_RIGHTS_FILE_ALL; + io->in.file_attributes = FILE_ATTRIBUTE_NORMAL; + io->in.share_access = NTCREATEX_SHARE_ACCESS_READ | + NTCREATEX_SHARE_ACCESS_WRITE | + NTCREATEX_SHARE_ACCESS_DELETE; + io->in.create_disposition = NTCREATEX_DISP_OPEN_IF; + io->in.create_options = NTCREATEX_OPTIONS_SEQUENTIAL_ONLY | + NTCREATEX_OPTIONS_ASYNC_ALERT | + NTCREATEX_OPTIONS_NON_DIRECTORY_FILE | + 0x00200000; + io->in.fname = name; + + if (dir) { + io->in.create_options = NTCREATEX_OPTIONS_DIRECTORY; + io->in.share_access &= ~NTCREATEX_SHARE_ACCESS_DELETE; + io->in.file_attributes = FILE_ATTRIBUTE_DIRECTORY; + io->in.create_disposition = NTCREATEX_DISP_CREATE; + } + + ZERO_STRUCT(*ls); + ls->lease_key[0] = leasekey; + ls->lease_key[1] = ~leasekey; + ls->lease_state = leasestate; + io->in.lease_request = ls; +} + +#define CHECK_CREATED(__io, __created, __attribute) \ + do { \ + if (__created) { \ + CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_CREATED); \ + } else { \ + CHECK_VAL((__io)->out.create_action, NTCREATEX_ACTION_EXISTED); \ + } \ + CHECK_VAL((__io)->out.alloc_size, 0); \ + CHECK_VAL((__io)->out.size, 0); \ + CHECK_VAL((__io)->out.file_attr, (__attribute)); \ + CHECK_VAL((__io)->out.reserved2, 0); \ + } while(0) + +#define CHECK_LEASE(__io, __state, __oplevel, __key) \ + do { \ + if (__oplevel) { \ + CHECK_VAL((__io)->out.oplock_level, SMB2_OPLOCK_LEVEL_LEASE); \ + CHECK_VAL((__io)->out.lease_response.lease_key[0], (__key)); \ + CHECK_VAL((__io)->out.lease_response.lease_key[1], ~(__key)); \ + CHECK_VAL((__io)->out.lease_response.lease_state, (__state)); \ + } else { \ + CHECK_VAL((__io)->out.oplock_level, SMB2_OPLOCK_LEVEL_NONE); \ + CHECK_VAL((__io)->out.lease_response.lease_key[0], 0); \ + CHECK_VAL((__io)->out.lease_response.lease_key[1], 0); \ + CHECK_VAL((__io)->out.lease_response.lease_state, 0); \ + } \ + \ + CHECK_VAL((__io)->out.lease_response.lease_flags, 0); \ + CHECK_VAL((__io)->out.lease_response.lease_duration, 0); \ + } while(0) \ + +static const uint64_t LEASE1 = 0xBADC0FFEE0DDF00Dull; +static const uint64_t LEASE2 = 0xDEADBEEFFEEDBEADull; +static const uint64_t LEASE3 = 0xDAD0FFEDD00DF00Dull; + +#define NRESULTS 8 +static const int request_results[NRESULTS][2] = { + { SMB2_LEASE_NONE, SMB2_LEASE_NONE }, + { SMB2_LEASE_READ, SMB2_LEASE_READ }, + { SMB2_LEASE_HANDLE, SMB2_LEASE_NONE, }, + { SMB2_LEASE_WRITE, SMB2_LEASE_NONE }, + { SMB2_LEASE_READ|SMB2_LEASE_HANDLE, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE }, + { SMB2_LEASE_READ|SMB2_LEASE_WRITE, + SMB2_LEASE_READ|SMB2_LEASE_WRITE }, + { SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, SMB2_LEASE_NONE }, + { SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE }, +}; + +static bool test_lease_request(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io; + struct smb2_lease ls; + struct smb2_handle h1, h2; + NTSTATUS status; + const char *fname = "lease.dat"; + const char *fname2 = "lease2.dat"; + const char *sname = "lease.dat:stream"; + const char *dname = "lease.dir"; + bool ret = true; + int i; + + smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname2); + smb2_util_rmdir(tree, dname); + + /* Win7 is happy to grant RHW leases on files. */ + smb2_lease_create(&io, &ls, false, fname, LEASE1, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + h1 = io.out.file.handle; + CHECK_CREATED(&io, true, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, + true, LEASE1); + + /* But will reject leases on directories. */ + smb2_lease_create(&io, &ls, true, dname, LEASE2, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, true, FILE_ATTRIBUTE_DIRECTORY); + CHECK_LEASE(&io, SMB2_LEASE_NONE, false, 0); + smb2_util_close(tree, io.out.file.handle); + + /* Also rejects multiple files leased under the same key. */ + smb2_lease_create(&io, &ls, true, fname2, LEASE1, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_INVALID_PARAMETER); + + /* And grants leases on streams (with separate leasekey). */ + smb2_lease_create(&io, &ls, false, sname, LEASE2, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE); + status = smb2_create(tree, mem_ctx, &io); + h2 = io.out.file.handle; + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, true, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, + true, LEASE2); + smb2_util_close(tree, h2); + + smb2_util_close(tree, h1); + + /* Now see what combos are actually granted. */ + for (i = 0; i < NRESULTS; i++) { + torture_comment(tctx, "Testing lease type %x, expecting %x\n", + request_results[i][0], request_results[i][1]); + smb2_lease_create(&io, &ls, false, fname, LEASE1, + request_results[i][0]); + status = smb2_create(tree, mem_ctx, &io); + h2 = io.out.file.handle; + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, request_results[i][1], true, LEASE1); + smb2_util_close(tree, io.out.file.handle); + } + + done: + smb2_util_close(tree, h1); + smb2_util_close(tree, h2); + + smb2_util_unlink(tree, fname); + smb2_util_unlink(tree, fname2); + smb2_util_rmdir(tree, dname); + + talloc_free(mem_ctx); + + return ret; +} + +static bool test_lease_upgrade(struct torture_context *tctx, + struct smb2_tree *tree) +{ + TALLOC_CTX *mem_ctx = talloc_new(tctx); + struct smb2_create io; + struct smb2_lease ls; + struct smb2_handle h, hnew; + NTSTATUS status; + const char *fname = "lease.dat"; + bool ret = true; + + smb2_util_unlink(tree, fname); + + /* Grab a RH lease. */ + smb2_lease_create(&io, &ls, false, fname, LEASE1, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, true, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE, true, LEASE1); + h = io.out.file.handle; + + /* Upgrades (sidegrades?) to RW leave us with an RH. */ + smb2_lease_create(&io, &ls, false, fname, LEASE1, + SMB2_LEASE_READ|SMB2_LEASE_WRITE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE, true, LEASE1); + hnew = io.out.file.handle; + + smb2_util_close(tree, hnew); + + /* Upgrade to RHW lease. */ + smb2_lease_create(&io, &ls, false, fname, LEASE1, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, + true, LEASE1); + hnew = io.out.file.handle; + + smb2_util_close(tree, h); + h = hnew; + + /* Attempt to downgrade - original lease state is maintained. */ + smb2_lease_create(&io, &ls, false, fname, LEASE1, + SMB2_LEASE_READ|SMB2_LEASE_HANDLE); + status = smb2_create(tree, mem_ctx, &io); + CHECK_STATUS(status, NT_STATUS_OK); + CHECK_CREATED(&io, false, FILE_ATTRIBUTE_ARCHIVE); + CHECK_LEASE(&io, SMB2_LEASE_READ|SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE, + true, LEASE1); + hnew = io.out.file.handle; + + smb2_util_close(tree, hnew); + + done: + smb2_util_close(tree, h); + smb2_util_close(tree, hnew); + + smb2_util_unlink(tree, fname); + + talloc_free(mem_ctx); + + return ret; +} + +struct torture_suite *torture_smb2_lease_init(void) +{ + struct torture_suite *suite = + torture_suite_create(talloc_autofree_context(), "LEASE"); + + torture_suite_add_1smb2_test(suite, "REQUEST", test_lease_request); + torture_suite_add_1smb2_test(suite, "UPGRADE", test_lease_upgrade); + + suite->description = talloc_strdup(suite, "SMB2-LEASE tests"); + + return suite; +} diff --git a/source4/torture/smb2/smb2.c b/source4/torture/smb2/smb2.c index 9418650de4..64456aaed5 100644 --- a/source4/torture/smb2/smb2.c +++ b/source4/torture/smb2/smb2.c @@ -100,11 +100,11 @@ static bool wrap_simple_2smb2_test(struct torture_context *torture_ctx, } -_PUBLIC_ struct torture_test *torture_suite_add_2smb2_test(struct torture_suite *suite, - const char *name, - bool (*run)(struct torture_context *, - struct smb2_tree *, - struct smb2_tree *)) +struct torture_test *torture_suite_add_2smb2_test(struct torture_suite *suite, + const char *name, + bool (*run)(struct torture_context *, + struct smb2_tree *, + struct smb2_tree *)) { struct torture_test *test; struct torture_tcase *tcase; @@ -139,8 +139,9 @@ NTSTATUS torture_smb2_init(void) torture_suite_add_suite(suite, torture_smb2_read_init()); torture_suite_add_suite(suite, torture_smb2_create_init()); torture_suite_add_simple_test(suite, "NOTIFY", torture_smb2_notify); - torture_suite_add_2smb2_test(suite, "PERSISTENT-HANDLES1", torture_smb2_persistent_handles1); + torture_suite_add_suite(suite, torture_smb2_durable_open_init()); torture_suite_add_1smb2_test(suite, "OPLOCK-BATCH1", torture_smb2_oplock_batch1); + torture_suite_add_suite(suite, torture_smb2_lease_init()); suite->description = talloc_strdup(suite, "SMB2-specific tests"); |