The branch, master has been updated via 1a43d86... s4:prog_guide4.txt: remove obsolete comments via a88b288... s4: Fixed the programming guide to reflect the current tree. via b55d076... s4-kdc: Migrate to tsocket_address. via a5bdab8... tsocket: Fixed tsocket_guide.txt asciidoc syntax. via e33ae22... tsocket: Fixed documentation for tsocket_address_bsd_sockaddr(). via ab04dd3... tsocket: Fixed typo in LGPL header. via edbf2ca... tsocket: add tsocket_address_bsd_sockaddr() and tsocket_address_bsd_from_sockaddr() from 4a19ada... smbtorture4: Add rpc-samba3-getaliasmembership-0
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 1a43d863be50be5bdcb8cde4adf30f7fd627f8ef Author: Stefan Metzmacher <me...@samba.org> Date: Tue Dec 15 16:52:00 2009 +0100 s4:prog_guide4.txt: remove obsolete comments metze commit a88b28850bb1cf5e1e40d49c05054ccd445ac0ed Author: Andreas Schneider <a...@redhat.com> Date: Tue Dec 15 16:46:03 2009 +0100 s4: Fixed the programming guide to reflect the current tree. commit b55d07615be78c582f790a498292a76a77259374 Author: Andreas Schneider <a...@redhat.com> Date: Tue Dec 15 12:58:40 2009 +0100 s4-kdc: Migrate to tsocket_address. commit a5bdab8b32768282270315f880f980d99ebb9a2e Author: Andreas Schneider <a...@redhat.com> Date: Tue Dec 15 12:58:18 2009 +0100 tsocket: Fixed tsocket_guide.txt asciidoc syntax. commit e33ae22b87597f31caefd5466bb8e8f240405972 Author: Andreas Schneider <a...@redhat.com> Date: Tue Dec 15 12:57:35 2009 +0100 tsocket: Fixed documentation for tsocket_address_bsd_sockaddr(). commit ab04dd3be743806bf3c9cf9db4b5326ce0476bf5 Author: Andreas Schneider <a...@redhat.com> Date: Tue Dec 15 12:56:44 2009 +0100 tsocket: Fixed typo in LGPL header. commit edbf2caa6f8273227229cd8f1b293e95c6a6122d Author: Stefan Metzmacher <me...@samba.org> Date: Wed Nov 4 19:03:41 2009 +0100 tsocket: add tsocket_address_bsd_sockaddr() and tsocket_address_bsd_from_sockaddr() metze ----------------------------------------------------------------------- Summary of changes: lib/tsocket/tsocket.c | 2 +- lib/tsocket/tsocket.h | 17 ++- lib/tsocket/tsocket_bsd.c | 56 +++++++- lib/tsocket/tsocket_guide.txt | 317 ++++++++++++++++++++++------------------ lib/tsocket/tsocket_helpers.c | 2 +- lib/tsocket/tsocket_internal.h | 2 +- prog_guide4.txt | 63 +++----- source4/kdc/kdc.c | 69 +++++++-- source4/kdc/kdc.h | 6 +- source4/kdc/kpasswdd.c | 23 +++- 10 files changed, 349 insertions(+), 208 deletions(-) Changeset truncated at 500 lines: diff --git a/lib/tsocket/tsocket.c b/lib/tsocket/tsocket.c index 55f1af3..b8dd6c8 100644 --- a/lib/tsocket/tsocket.c +++ b/lib/tsocket/tsocket.c @@ -3,7 +3,7 @@ Copyright (C) Stefan Metzmacher 2009 - ** NOTE! The following LGPL license applies to the tevent + ** NOTE! The following LGPL license applies to the tsocket ** library. This does NOT imply that all of Samba is released ** under the LGPL diff --git a/lib/tsocket/tsocket.h b/lib/tsocket/tsocket.h index ae73113..7e9cf9e 100644 --- a/lib/tsocket/tsocket.h +++ b/lib/tsocket/tsocket.h @@ -3,7 +3,7 @@ Copyright (C) Stefan Metzmacher 2009 - ** NOTE! The following LGPL license applies to the tevent + ** NOTE! The following LGPL license applies to the tsocket ** library. This does NOT imply that all of Samba is released ** under the LGPL @@ -179,6 +179,21 @@ int _tstream_unix_socketpair(TALLOC_CTX *mem_ctx1, _tstream_unix_socketpair(mem_ctx1, stream1, mem_ctx2, stream2, \ __location__) +struct sockaddr; + +int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, + struct sockaddr *sa, + size_t sa_socklen, + struct tsocket_address **_addr, + const char *location); +#define tsocket_address_bsd_from_sockaddr(mem_ctx, sa, sa_socklen, _addr) \ + _tsocket_address_bsd_from_sockaddr(mem_ctx, sa, sa_socklen, _addr, \ + __location__) + +ssize_t tsocket_address_bsd_sockaddr(const struct tsocket_address *addr, + struct sockaddr *sa, + size_t sa_socklen); + int _tstream_bsd_existing_socket(TALLOC_CTX *mem_ctx, int fd, struct tstream_context **_stream, diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 05f5be1..1c1e580 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -3,7 +3,7 @@ Copyright (C) Stefan Metzmacher 2009 - ** NOTE! The following LGPL license applies to the tevent + ** NOTE! The following LGPL license applies to the tsocket ** library. This does NOT imply that all of Samba is released ** under the LGPL @@ -201,11 +201,11 @@ struct tsocket_address_bsd { } u; }; -static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, - struct sockaddr *sa, - socklen_t sa_socklen, - struct tsocket_address **_addr, - const char *location) +int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, + struct sockaddr *sa, + size_t sa_socklen, + struct tsocket_address **_addr, + const char *location) { struct tsocket_address *addr; struct tsocket_address_bsd *bsda; @@ -259,6 +259,50 @@ static int _tsocket_address_bsd_from_sockaddr(TALLOC_CTX *mem_ctx, return 0; } +ssize_t tsocket_address_bsd_sockaddr(const struct tsocket_address *addr, + struct sockaddr *sa, + size_t sa_socklen) +{ + struct tsocket_address_bsd *bsda = talloc_get_type(addr->private_data, + struct tsocket_address_bsd); + ssize_t rlen = 0; + + if (!bsda) { + errno = EINVAL; + return -1; + } + + switch (bsda->u.sa.sa_family) { + case AF_UNIX: + rlen = sizeof(struct sockaddr_un); + break; + case AF_INET: + rlen = sizeof(struct sockaddr_in); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + rlen = sizeof(struct sockaddr_in6); + break; +#endif + default: + errno = EAFNOSUPPORT; + return -1; + } + + if (sa_socklen < rlen) { + errno = EINVAL; + return -1; + } + + if (sa_socklen > sizeof(struct sockaddr_storage)) { + memset(sa, 0, sa_socklen); + sa_socklen = sizeof(struct sockaddr_storage); + } + + memcpy(sa, &bsda->u.ss, sa_socklen); + return rlen; +} + int _tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx, const char *fam, const char *addr, diff --git a/lib/tsocket/tsocket_guide.txt b/lib/tsocket/tsocket_guide.txt index ed903c6..dfe2dd4 100644 --- a/lib/tsocket/tsocket_guide.txt +++ b/lib/tsocket/tsocket_guide.txt @@ -32,15 +32,15 @@ endpoint for debugging. Callers should not try to parse the string! The should use additional methods of the specific tsocket_address implemention to get more details. - char *tsocket_address_string(const struct tsocket_address *addr, - TALLOC_CTX *mem_ctx); + char *tsocket_address_string(const struct tsocket_address *addr, + TALLOC_CTX *mem_ctx); There's a function to create a copy of the tsocket_address. This is useful when before doing modifications to a socket via additional methods of the specific tsocket_address implementation. - struct tsocket_address *tsocket_address_copy(const struct tsocket_address *addr, - TALLOC_CTX *mem_ctx); + struct tsocket_address *tsocket_address_copy(const struct tsocket_address *addr, + TALLOC_CTX *mem_ctx); The tdgram_context abstraction ============================== @@ -58,23 +58,24 @@ when a datagram is available or an error happened. The callback is then supposed to get the result by calling tdgram_recvfrom_recv() on the 'tevent_req'. It returns -1 -and sets *perrno to the actual 'errno' on failure. +and sets '*perrno' to the actual 'errno' on failure. Otherwise it returns the length of the datagram -(0 is never returned!). *buf will contain the buffer of the -datagram and *src the abstracted tsocket_address of the sender +(0 is never returned!). '*buf' will contain the buffer of the +datagram and '*src' the abstracted tsocket_address of the sender of the received datagram. The caller can only have one outstanding tdgram_recvfrom_send() -at a time otherwise the caller will get *perrno = EBUSY. +at a time otherwise the caller will get '*perrno = EBUSY'. + + struct tevent_req *tdgram_recvfrom_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tdgram_context *dgram); -struct tevent_req *tdgram_recvfrom_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tdgram_context *dgram); -ssize_t tdgram_recvfrom_recv(struct tevent_req *req, - int *perrno, - TALLOC_CTX *mem_ctx, - uint8_t **buf, - struct tsocket_address **src); + ssize_t tdgram_recvfrom_recv(struct tevent_req *req, + int *perrno, + TALLOC_CTX *mem_ctx, + uint8_t **buf, + struct tsocket_address **src); The tdgram_sendto_send() method can be called to send a datagram (specified by a buf/len) to a destination endpoint @@ -86,35 +87,37 @@ has delivered the datagram to the "wire". The callback is then supposed to get the result by calling tdgram_sendto_recv() on the 'tevent_req'. It returns -1 -and sets *perrno to the actual 'errno' on failure. +and sets '*perrno' to the actual 'errno' on failure. Otherwise it returns the length of the datagram (0 is never returned!). The caller can only have one outstanding tdgram_sendto_send() -at a time otherwise the caller will get *perrno = EBUSY. +at a time otherwise the caller will get '*perrno = EBUSY'. -struct tevent_req *tdgram_sendto_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tdgram_context *dgram, - const uint8_t *buf, size_t len, - const struct tsocket_address *dst); -ssize_t tdgram_sendto_recv(struct tevent_req *req, - int *perrno); + struct tevent_req *tdgram_sendto_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tdgram_context *dgram, + const uint8_t *buf, size_t len, + const struct tsocket_address *dst); + + ssize_t tdgram_sendto_recv(struct tevent_req *req, + int *perrno); The tdgram_disconnect_send() method should be used to normally shutdown/close the abstracted socket. The caller should make sure there're no outstanding tdgram_recvfrom_send() -and tdgram_sendto_send() calls otherwise the caller will get *perrno = EBUSY. +and tdgram_sendto_send() calls otherwise the caller will get '*perrno = EBUSY'. Note: you can always use talloc_free(tdgram) to cleanup the resources of the tdgram_context on a fatal error. -struct tevent_req *tdgram_disconnect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tdgram_context *dgram); -int tdgram_disconnect_recv(struct tevent_req *req, - int *perrno); + struct tevent_req *tdgram_disconnect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tdgram_context *dgram); + + int tdgram_disconnect_recv(struct tevent_req *req, + int *perrno); The tstream_context abstraction =============================== @@ -130,7 +133,7 @@ but not consumed yet. It returns -1 and sets 'errno' on failure. Otherwise it returns the number of uncomsumed bytes (it can return 0!). -ssize_t tstream_pending_bytes(struct tstream_context *stream); + ssize_t tstream_pending_bytes(struct tstream_context *stream); The tstream_readv_send() method can be called to read for a specific amount of bytes from the stream into the buffers @@ -144,20 +147,21 @@ filled with bytes from the socket or an error happened. The callback is then supposed to get the result by calling tstream_readv_recv() on the 'tevent_req'. It returns -1 -and sets *perrno to the actual 'errno' on failure. +and sets '*perrno' to the actual 'errno' on failure. Otherwise it returns the length of the datagram (0 is never returned!). The caller can only have one outstanding tstream_readv_send() at a time otherwise the caller will get *perrno = EBUSY. -struct tevent_req *tstream_readv_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tstream_context *stream, - struct iovec *vector, - size_t count); -int tstream_readv_recv(struct tevent_req *req, - int *perrno); + struct tevent_req *tstream_readv_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream, + struct iovec *vector, + size_t count); + + int tstream_readv_recv(struct tevent_req *req, + int *perrno); The tstream_writev_send() method can be called to write buffers in the given iovec vector into the stream socket. @@ -169,35 +173,37 @@ has delivered the all buffers to the "wire". The callback is then supposed to get the result by calling tstream_writev_recv() on the 'tevent_req'. It returns -1 -and sets *perrno to the actual 'errno' on failure. +and sets '*perrno' to the actual 'errno' on failure. Otherwise it returns the total amount of bytes sent. (0 is never returned!). The caller can only have one outstanding tstream_writev_send() -at a time otherwise the caller will get *perrno = EBUSY. +at a time otherwise the caller will get '*perrno = EBUSY'. -struct tevent_req *tstream_writev_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tstream_context *stream, - const struct iovec *vector, - size_t count); -int tstream_writev_recv(struct tevent_req *req, - int *perrno); + struct tevent_req *tstream_writev_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream, + const struct iovec *vector, + size_t count); + + int tstream_writev_recv(struct tevent_req *req, + int *perrno); The tstream_disconnect_send() method should be used to normally shutdown/close the abstracted socket. The caller should make sure there're no outstanding tstream_readv_send() -and tstream_writev_send() calls otherwise the caller will get *perrno = EBUSY. +and tstream_writev_send() calls otherwise the caller will get '*perrno = EBUSY'. Note: you can always use talloc_free(tstream) to cleanup the resources of the tstream_context on a fatal error. -struct tevent_req *tstream_disconnect_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tstream_context *stream); -int tstream_disconnect_recv(struct tevent_req *req, - int *perrno); + struct tevent_req *tstream_disconnect_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream); + + int tstream_disconnect_recv(struct tevent_req *req, + int *perrno); PDU receive helper functions ============================ @@ -221,17 +227,19 @@ and it's private state. See the 'dcerpc_read_ncacn_packet_send/recv' functions in Samba as an example. -typedef int (*tstream_readv_pdu_next_vector_t)(struct tstream_context *stream, - void *private_data, - TALLOC_CTX *mem_ctx, - struct iovec **vector, - size_t *count); -struct tevent_req *tstream_readv_pdu_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tstream_context *stream, - tstream_readv_pdu_next_vector_t next_vector_fn, - void *next_vector_private); -int tstream_readv_pdu_recv(struct tevent_req *req, int *perrno); + typedef int (*tstream_readv_pdu_next_vector_t)(struct tstream_context *stream, + void *private_data, + TALLOC_CTX *mem_ctx, + struct iovec **vector, + size_t *count); + + struct tevent_req *tstream_readv_pdu_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream, + tstream_readv_pdu_next_vector_t next_vector_fn, + void *next_vector_private); + + int tstream_readv_pdu_recv(struct tevent_req *req, int *perrno); Async 'tevent_queue' based helper functions =========================================== @@ -245,30 +253,33 @@ There're some helpers using 'tevent_queue' to make it easier for callers. The functions just get a 'queue' argument and serialize the operations. -struct tevent_req *tdgram_sendto_queue_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tdgram_context *dgram, - struct tevent_queue *queue, - const uint8_t *buf, - size_t len, - struct tsocket_address *dst); -ssize_t tdgram_sendto_queue_recv(struct tevent_req *req, int *perrno); - -struct tevent_req *tstream_readv_pdu_queue_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tstream_context *stream, - struct tevent_queue *queue, - tstream_readv_pdu_next_vector_t next_vector_fn, - void *next_vector_private); -int tstream_readv_pdu_queue_recv(struct tevent_req *req, int *perrno); - -struct tevent_req *tstream_writev_queue_send(TALLOC_CTX *mem_ctx, - struct tevent_context *ev, - struct tstream_context *stream, - struct tevent_queue *queue, - const struct iovec *vector, - size_t count); -int tstream_writev_queue_recv(struct tevent_req *req, int *perrno); + struct tevent_req *tdgram_sendto_queue_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tdgram_context *dgram, + struct tevent_queue *queue, + const uint8_t *buf, + size_t len, + struct tsocket_address *dst); + + ssize_t tdgram_sendto_queue_recv(struct tevent_req *req, int *perrno); + + struct tevent_req *tstream_readv_pdu_queue_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream, + struct tevent_queue *queue, + tstream_readv_pdu_next_vector_t next_vector_fn, + void *next_vector_private); + + int tstream_readv_pdu_queue_recv(struct tevent_req *req, int *perrno); + + struct tevent_req *tstream_writev_queue_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct tstream_context *stream, + struct tevent_queue *queue, + const struct iovec *vector, + size_t count); + + int tstream_writev_queue_recv(struct tevent_req *req, int *perrno); BSD sockets: ipv4, ipv6 and unix ================================ @@ -286,26 +297,26 @@ ip address string based on the selected family which gets mapped to "0.0.0.0" or "::". It return -1 and set errno on error. Otherwise it returns 0. -int tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx, - const char *family, - const char *addr_string, - uint16_t port, - struct tsocket_address **addr); + int tsocket_address_inet_from_strings(TALLOC_CTX *mem_ctx, + const char *family, + const char *addr_string, + uint16_t port, + struct tsocket_address **addr); To get the ip address string of an existing 'inet' tsocket_address you can use the tsocket_address_inet_addr_string() function. It will return NULL and set errno to EINVAL if the tsocket_address doesn't represent an ipv4 or ipv6 endpoint address. -char *tsocket_address_inet_addr_string(const struct tsocket_address *addr, - TALLOC_CTX *mem_ctx); + char *tsocket_address_inet_addr_string(const struct tsocket_address *addr, + TALLOC_CTX *mem_ctx); To get the port number of an existing 'inet' tsocket_address you can use the tsocket_address_inet_port() function. It will return 0 and set errno to EINVAL if the tsocket_address doesn't represent an ipv4 or ipv6 endpoint address. -uint16_t tsocket_address_inet_port(const struct tsocket_address *addr); + uint16_t tsocket_address_inet_port(const struct tsocket_address *addr); To set the port number of an existing 'inet' tsocket_address you can use the tsocket_address_inet_set_port() function. @@ -313,8 +324,8 @@ It will return -1 and set errno to EINVAL if the tsocket_address doesn't represent an ipv4 or ipv6 endpoint address. It returns 0 on success. -int tsocket_address_inet_set_port(struct tsocket_address *addr, - uint16_t port); + int tsocket_address_inet_set_port(struct tsocket_address *addr, + uint16_t port); You can use the tsocket_address_unix_from_path() function to create a tsocket_address for unix domain @@ -324,17 +335,17 @@ the low level kernel supports the function will return -1 and set errno to ENAMETOOLONG. On success it returns 0. -int tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx, - const char *path, - struct tsocket_address **addr); + int tsocket_address_unix_from_path(TALLOC_CTX *mem_ctx, + const char *path, + struct tsocket_address **addr); To get the path of an 'unix' tsocket_address you can use the tsocket_address_unix_path() function. It will return NULL and set errno to EINVAL if the tsocket_address doesn't represent an unix domain endpoint path. -char *tsocket_address_unix_path(const struct tsocket_address *addr, - TALLOC_CTX *mem_ctx); + char *tsocket_address_unix_path(const struct tsocket_address *addr, + TALLOC_CTX *mem_ctx); You can use tdgram_inet_udp_socket() to create a tdgram_context for ipv4 or ipv6 UDP communication. "local_address" has to be @@ -343,10 +354,10 @@ endpoint. "remote_address" can be NULL or an 'inet' tsocket_address presenting a remote endpoint. It returns -1 ans sets errno on error and it returns 0 on success. -int tdgram_inet_udp_socket(const struct tsocket_address *local_address, - const struct tsocket_address *remote_address, - TALLOC_CTX *mem_ctx, -- Samba Shared Repository