mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
Merge branch 'master' of git://git.samba.org/samba
This commit is contained in:
commit
309473f938
@ -1,5 +1,6 @@
|
||||
TALLOC_OBJ = $(tallocdir)/talloc.o
|
||||
|
||||
TALLOC_SHLIB = libtalloc.$(SHLIBEXT)
|
||||
TALLOC_SOLIB = libtalloc.$(SHLIBEXT).$(TALLOC_VERSION)
|
||||
TALLOC_SONAME = libtalloc.$(SHLIBEXT).$(TALLOC_VERSION_MAJOR)
|
||||
TALLOC_STLIB = libtalloc.a
|
||||
@ -25,6 +26,10 @@ install:: all
|
||||
if [ -f talloc.3 ];then ${INSTALLCMD} -m 644 talloc.3 $(DESTDIR)$(mandir)/man3; fi
|
||||
which swig >/dev/null 2>&1 && ${INSTALLCMD} -d $(DESTDIR)`swig -swiglib` || true
|
||||
which swig >/dev/null 2>&1 && ${INSTALLCMD} -m 644 talloc.i $(DESTDIR)`swig -swiglib` || true
|
||||
rm -f $(DESTDIR)$(libdir)/$(TALLOC_SONAME)
|
||||
ln -s $(TALLOC_SOLIB) $(DESTDIR)$(libdir)/$(TALLOC_SONAME)
|
||||
rm -f $(DESTDIR)$(libdir)/$(TALLOC_SHLIB)
|
||||
ln -s $(TALLOC_SOLIB) $(DESTDIR)$(libdir)/$(TALLOC_SHLIB)
|
||||
|
||||
doc:: talloc.3 talloc.3.html
|
||||
|
||||
|
@ -9,6 +9,7 @@ exec_prefix = @exec_prefix@
|
||||
bindir = @bindir@
|
||||
includedir = @includedir@
|
||||
libdir = @libdir@
|
||||
mandir = @mandir@
|
||||
VPATH = @srcdir@:@libreplacedir@
|
||||
srcdir = @srcdir@
|
||||
builddir = @builddir@
|
||||
|
@ -61,9 +61,9 @@ doc:: manpages/tdbbackup.8 manpages/tdbdump.8 manpages/tdbtool.8
|
||||
-test -z "$(XSLTPROC)" || $(XSLTPROC) -o $@ http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl $<
|
||||
|
||||
installdocs::
|
||||
${INSTALLCMD} -d $(DESTDIR)$(mandir)/man1
|
||||
for I in manpages/*.1; do \
|
||||
${INSTALLCMD} -m 644 $$I $(DESTDIR)$(mandir)/man1 \
|
||||
${INSTALLCMD} -d $(DESTDIR)$(mandir)/man8
|
||||
for I in manpages/*.8; do \
|
||||
${INSTALLCMD} -m 644 $$I $(DESTDIR)$(mandir)/man8; \
|
||||
done
|
||||
|
||||
install-python:: build-python
|
||||
@ -91,6 +91,10 @@ installheaders:: installdirs
|
||||
installlibs:: all installdirs
|
||||
cp tdb.pc $(DESTDIR)$(libdir)/pkgconfig
|
||||
cp $(TDB_STLIB) $(TDB_SOLIB) $(DESTDIR)$(libdir)
|
||||
rm -f $(DESTDIR)$(libdir)/libtdb.$(SHLIBEXT)
|
||||
ln -s $(TDB_SOLIB) $(DESTDIR)$(libdir)/libtdb.$(SHLIBEXT)
|
||||
rm -f $(DESTDIR)$(libdir)/$(TDB_SONAME)
|
||||
ln -s $(TDB_SOLIB) $(DESTDIR)$(libdir)/$(TDB_SONAME)
|
||||
|
||||
$(TDB_STLIB): $(TDB_OBJ)
|
||||
ar -rv $(TDB_STLIB) $(TDB_OBJ)
|
||||
|
@ -26,6 +26,10 @@ installheaders:: installdirs
|
||||
installlibs:: installdirs
|
||||
cp tevent.pc $(DESTDIR)$(libdir)/pkgconfig
|
||||
cp $(TEVENT_STLIB) $(TEVENT_SOLIB) $(DESTDIR)$(libdir)
|
||||
rm -f $(DESTDIR)$(libdir)/$(TEVENT_SONAME)
|
||||
ln -s $(TEVENT_SOLIB) $(DESTDIR)$(libdir)/$(TEVENT_SONAME)
|
||||
rm -f $(DESTDIR)$(libdir)/$(TEVENT_SOBASE)
|
||||
ln -s $(TEVENT_SOLIB) $(DESTDIR)$(libdir)/$(TEVENT_SOBASE)
|
||||
|
||||
install:: all installdirs installheaders installlibs $(PYTHON_INSTALL_TARGET)
|
||||
|
||||
|
@ -27,11 +27,6 @@
|
||||
* @brief time handling functions
|
||||
*/
|
||||
|
||||
#ifndef TIME_T_MIN
|
||||
/* we use 0 here, because (time_t)-1 means error */
|
||||
#define TIME_T_MIN 0
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_LONG == 8)
|
||||
#define TIME_FIXUP_CONSTANT_INT 11644473600L
|
||||
#elif (SIZEOF_LONG_LONG == 8)
|
||||
@ -40,15 +35,6 @@
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* we use the INT32_MAX here as on 64 bit systems,
|
||||
* gmtime() fails with INT64_MAX
|
||||
*/
|
||||
|
||||
#ifndef TIME_T_MAX
|
||||
#define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t))
|
||||
#endif
|
||||
|
||||
/**
|
||||
External access to time_t_min and time_t_max.
|
||||
**/
|
||||
|
@ -23,6 +23,20 @@
|
||||
#define _PUBLIC_
|
||||
#endif
|
||||
|
||||
#ifndef TIME_T_MIN
|
||||
/* we use 0 here, because (time_t)-1 means error */
|
||||
#define TIME_T_MIN 0
|
||||
#endif
|
||||
|
||||
/*
|
||||
* we use the INT32_MAX here as on 64 bit systems,
|
||||
* gmtime() fails with INT64_MAX
|
||||
*/
|
||||
#ifndef TIME_T_MAX
|
||||
#define TIME_T_MAX MIN(INT32_MAX,_TYPE_MAXIMUM(time_t))
|
||||
#endif
|
||||
|
||||
|
||||
/* 64 bit time (100 nanosec) 1601 - cifs6.txt, section 3.5, page 30, 4 byte aligned */
|
||||
typedef uint64_t NTTIME;
|
||||
|
||||
|
@ -120,6 +120,7 @@ fi
|
||||
|
||||
m4_include(../lib/socket_wrapper/config.m4)
|
||||
m4_include(../lib/nss_wrapper/config.m4)
|
||||
m4_include(../lib/util/time.m4)
|
||||
|
||||
m4_include(m4/swat.m4)
|
||||
|
||||
@ -2216,15 +2217,6 @@ if test x"$samba_cv_HAVE_FUNCTION_MACRO" = x"yes"; then
|
||||
AC_DEFINE(HAVE_FUNCTION_MACRO,1,[Whether there is a __FUNCTION__ macro])
|
||||
fi
|
||||
|
||||
AC_CACHE_CHECK([if gettimeofday takes tz argument],samba_cv_HAVE_GETTIMEOFDAY_TZ,[
|
||||
AC_TRY_LINK([
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>], [struct timeval tv; return gettimeofday(&tv, NULL);],
|
||||
samba_cv_HAVE_GETTIMEOFDAY_TZ=yes,
|
||||
samba_cv_HAVE_GETTIMEOFDAY_TZ=no)])
|
||||
if test x"$samba_cv_HAVE_GETTIMEOFDAY_TZ" = x"yes"; then
|
||||
AC_DEFINE(HAVE_GETTIMEOFDAY_TZ,1,[Whether gettimeofday takes a tz argument])
|
||||
fi
|
||||
|
||||
if test x"$samba_cv_WITH_PROFILE" = x"yes"; then
|
||||
|
||||
|
@ -1059,14 +1059,12 @@ void cli_put_dos_date3(struct cli_state *cli, char *buf, int offset, time_t unix
|
||||
time_t cli_make_unix_date(struct cli_state *cli, const void *date_ptr);
|
||||
time_t cli_make_unix_date2(struct cli_state *cli, const void *date_ptr);
|
||||
time_t cli_make_unix_date3(struct cli_state *cli, const void *date_ptr);
|
||||
bool nt_time_equals(const NTTIME *nt1, const NTTIME *nt2);
|
||||
void TimeInit(void);
|
||||
void get_process_uptime(struct timeval *ret_time);
|
||||
time_t nt_time_to_unix_abs(const NTTIME *nt);
|
||||
time_t uint64s_nt_time_to_unix_abs(const uint64_t *src);
|
||||
void unix_timespec_to_nt_time(NTTIME *nt, struct timespec ts);
|
||||
void unix_to_nt_time_abs(NTTIME *nt, time_t t);
|
||||
bool null_mtime(time_t mtime);
|
||||
const char *time_to_asc(const time_t t);
|
||||
const char *display_time(NTTIME nttime);
|
||||
bool nt_time_is_set(const NTTIME *nt);
|
||||
@ -5396,6 +5394,7 @@ NTSTATUS rpc_transport_np_init(TALLOC_CTX *mem_ctx, struct cli_state *cli,
|
||||
const struct ndr_syntax_id *abstract_syntax,
|
||||
struct rpc_cli_transport **presult);
|
||||
struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p);
|
||||
void rpccli_close_np_fd(struct rpc_pipe_client *p);
|
||||
|
||||
/* The following definitions come from rpc_client/rpc_transport_smbd.c */
|
||||
|
||||
@ -5426,11 +5425,15 @@ NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx,
|
||||
struct rpc_cli_smbd_conn *conn,
|
||||
const struct ndr_syntax_id *abstract_syntax,
|
||||
struct rpc_cli_transport **presult);
|
||||
struct cli_state *rpc_pipe_smbd_smb_conn(struct rpc_pipe_client *p);
|
||||
|
||||
/* The following definitions come from rpc_client/rpc_transport_sock.c */
|
||||
|
||||
NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
|
||||
struct rpc_cli_transport **presult);
|
||||
int rpccli_set_sock_timeout(struct rpc_pipe_client *rpccli, int timeout);
|
||||
void rpccli_close_sock_fd(struct rpc_pipe_client *rpccli);
|
||||
bool rpc_pipe_tcp_connection_ok(struct rpc_pipe_client *rpccli);
|
||||
|
||||
/* The following definitions come from rpc_client/cli_samr.c */
|
||||
|
||||
|
@ -28,14 +28,6 @@
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TIME_T_MIN
|
||||
#define TIME_T_MIN ((time_t)0 < (time_t) -1 ? (time_t) 0 \
|
||||
: ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1))
|
||||
#endif
|
||||
#ifndef TIME_T_MAX
|
||||
#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN)
|
||||
#endif
|
||||
|
||||
#define NTTIME_INFINITY (NTTIME)0x8000000000000000LL
|
||||
|
||||
#if (SIZEOF_LONG == 8)
|
||||
@ -44,53 +36,6 @@
|
||||
#define TIME_FIXUP_CONSTANT_INT 11644473600LL
|
||||
#endif
|
||||
|
||||
/*******************************************************************
|
||||
create a 16 bit dos packed date
|
||||
********************************************************************/
|
||||
static uint16_t make_dos_date1(struct tm *t)
|
||||
{
|
||||
uint16_t ret=0;
|
||||
ret = (((unsigned int)(t->tm_mon+1)) >> 3) | ((t->tm_year-80) << 1);
|
||||
ret = ((ret&0xFF)<<8) | (t->tm_mday | (((t->tm_mon+1) & 0x7) << 5));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
create a 16 bit dos packed time
|
||||
********************************************************************/
|
||||
static uint16_t make_dos_time1(struct tm *t)
|
||||
{
|
||||
uint16_t ret=0;
|
||||
ret = ((((unsigned int)t->tm_min >> 3)&0x7) | (((unsigned int)t->tm_hour) << 3));
|
||||
ret = ((ret&0xFF)<<8) | ((t->tm_sec/2) | ((t->tm_min & 0x7) << 5));
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
create a 32 bit dos packed date/time from some parameters
|
||||
This takes a GMT time and returns a packed localtime structure
|
||||
********************************************************************/
|
||||
static uint32_t make_dos_date(time_t unixdate, int zone_offset)
|
||||
{
|
||||
struct tm *t;
|
||||
uint32_t ret=0;
|
||||
|
||||
if (unixdate == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unixdate -= zone_offset;
|
||||
|
||||
t = gmtime(&unixdate);
|
||||
if (!t) {
|
||||
return 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
ret = make_dos_date1(t);
|
||||
ret = ((ret&0xFFFF)<<16) | make_dos_time1(t);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
parse a nttime as a large integer in a string and return a NTTIME
|
||||
@ -245,42 +190,6 @@ char *current_timestring(TALLOC_CTX *ctx, bool hires)
|
||||
return timeval_string(ctx, &tv, hires);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Put a dos date into a buffer (time/date format).
|
||||
This takes GMT time and puts local time in the buffer.
|
||||
********************************************************************/
|
||||
|
||||
static void put_dos_date(char *buf,int offset,time_t unixdate, int zone_offset)
|
||||
{
|
||||
uint32_t x = make_dos_date(unixdate, zone_offset);
|
||||
SIVAL(buf,offset,x);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Put a dos date into a buffer (date/time format).
|
||||
This takes GMT time and puts local time in the buffer.
|
||||
********************************************************************/
|
||||
|
||||
static void put_dos_date2(char *buf,int offset,time_t unixdate, int zone_offset)
|
||||
{
|
||||
uint32_t x = make_dos_date(unixdate, zone_offset);
|
||||
x = ((x&0xFFFF)<<16) | ((x&0xFFFF0000)>>16);
|
||||
SIVAL(buf,offset,x);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Put a dos 32 bit "unix like" date into a buffer. This routine takes
|
||||
GMT and converts it to LOCAL time before putting it (most SMBs assume
|
||||
localtime for this sort of date)
|
||||
********************************************************************/
|
||||
|
||||
static void put_dos_date3(char *buf,int offset,time_t unixdate, int zone_offset)
|
||||
{
|
||||
if (!null_mtime(unixdate)) {
|
||||
unixdate -= zone_offset;
|
||||
}
|
||||
SIVAL(buf,offset,unixdate);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
@ -289,17 +198,17 @@ static void put_dos_date3(char *buf,int offset,time_t unixdate, int zone_offset)
|
||||
|
||||
void srv_put_dos_date(char *buf,int offset,time_t unixdate)
|
||||
{
|
||||
put_dos_date(buf, offset, unixdate, server_zone_offset);
|
||||
push_dos_date(buf, offset, unixdate, server_zone_offset);
|
||||
}
|
||||
|
||||
void srv_put_dos_date2(char *buf,int offset, time_t unixdate)
|
||||
{
|
||||
put_dos_date2(buf, offset, unixdate, server_zone_offset);
|
||||
push_dos_date2(buf, offset, unixdate, server_zone_offset);
|
||||
}
|
||||
|
||||
void srv_put_dos_date3(char *buf,int offset,time_t unixdate)
|
||||
{
|
||||
put_dos_date3(buf, offset, unixdate, server_zone_offset);
|
||||
push_dos_date3(buf, offset, unixdate, server_zone_offset);
|
||||
}
|
||||
|
||||
void round_timespec(enum timestamp_set_resolution res, struct timespec *ts)
|
||||
@ -396,7 +305,7 @@ time_t make_unix_date2(const void *date_ptr, int zone_offset)
|
||||
time_t make_unix_date3(const void *date_ptr, int zone_offset)
|
||||
{
|
||||
time_t t = (time_t)IVAL(date_ptr,0);
|
||||
if (!null_mtime(t)) {
|
||||
if (!null_time(t)) {
|
||||
t += zone_offset;
|
||||
}
|
||||
return(t);
|
||||
@ -530,17 +439,17 @@ struct timespec interpret_long_date(const char *p)
|
||||
|
||||
void cli_put_dos_date(struct cli_state *cli, char *buf, int offset, time_t unixdate)
|
||||
{
|
||||
put_dos_date(buf, offset, unixdate, cli->serverzone);
|
||||
push_dos_date(buf, offset, unixdate, cli->serverzone);
|
||||
}
|
||||
|
||||
void cli_put_dos_date2(struct cli_state *cli, char *buf, int offset, time_t unixdate)
|
||||
{
|
||||
put_dos_date2(buf, offset, unixdate, cli->serverzone);
|
||||
push_dos_date2(buf, offset, unixdate, cli->serverzone);
|
||||
}
|
||||
|
||||
void cli_put_dos_date3(struct cli_state *cli, char *buf, int offset, time_t unixdate)
|
||||
{
|
||||
put_dos_date3(buf, offset, unixdate, cli->serverzone);
|
||||
push_dos_date3(buf, offset, unixdate, cli->serverzone);
|
||||
}
|
||||
|
||||
time_t cli_make_unix_date(struct cli_state *cli, const void *date_ptr)
|
||||
@ -558,14 +467,6 @@ time_t cli_make_unix_date3(struct cli_state *cli, const void *date_ptr)
|
||||
return make_unix_date3(date_ptr, cli->serverzone);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Check if two NTTIMEs are the same.
|
||||
****************************************************************************/
|
||||
|
||||
bool nt_time_equals(const NTTIME *nt1, const NTTIME *nt2)
|
||||
{
|
||||
return (*nt1 == *nt2);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Re-read the smb serverzone value.
|
||||
@ -746,17 +647,6 @@ void unix_to_nt_time_abs(NTTIME *nt, time_t t)
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
Check if it's a null mtime.
|
||||
****************************************************************************/
|
||||
|
||||
bool null_mtime(time_t mtime)
|
||||
{
|
||||
if (mtime == 0 || mtime == (time_t)0xFFFFFFFF || mtime == (time_t)-1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Utility function that always returns a const string even if localtime
|
||||
and asctime fail.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -88,6 +88,8 @@ static int commit_do(
|
||||
#elif HAVE_FSYNC
|
||||
result = fsync(fd);
|
||||
#else
|
||||
DEBUG(0, ("%s: WARNING: no commit support on this platform\n",
|
||||
MODULE));
|
||||
result = 0
|
||||
#endif
|
||||
if (result == 0) {
|
||||
|
@ -3035,12 +3035,30 @@ NTSTATUS rpc_pipe_bind(struct rpc_pipe_client *cli,
|
||||
unsigned int rpccli_set_timeout(struct rpc_pipe_client *rpc_cli,
|
||||
unsigned int timeout)
|
||||
{
|
||||
struct cli_state *cli = rpc_pipe_np_smb_conn(rpc_cli);
|
||||
struct cli_state *cli;
|
||||
|
||||
if (rpc_cli->transport->transport == NCACN_NP) {
|
||||
cli = rpc_pipe_np_smb_conn(rpc_cli);
|
||||
if (cli == NULL) {
|
||||
return 0;
|
||||
}
|
||||
return cli_set_timeout(cli, timeout);
|
||||
}
|
||||
|
||||
if (rpc_cli->transport->transport == NCACN_IP_TCP ||
|
||||
rpc_cli->transport->transport == NCALRPC) {
|
||||
return rpccli_set_sock_timeout(rpc_cli, timeout);
|
||||
}
|
||||
|
||||
if (rpc_cli->transport->transport == NCACN_INTERNAL) {
|
||||
cli = rpc_pipe_smbd_smb_conn(rpc_cli);
|
||||
if (!cli) {
|
||||
return 0;
|
||||
}
|
||||
return cli_set_timeout(cli, timeout);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool rpccli_get_pwd_hash(struct rpc_pipe_client *rpc_cli, uint8_t nt_hash[16])
|
||||
|
@ -182,6 +182,21 @@ NTSTATUS cli_do_rpc_ndr(struct rpc_pipe_client *cli,
|
||||
}
|
||||
|
||||
status = cli_do_rpc_ndr_recv(req, mem_ctx);
|
||||
|
||||
/*
|
||||
* NT_STATUS_IO_TIMEOUT indicates network problem,
|
||||
* tear the connection apart.
|
||||
*/
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
|
||||
if (cli->transport->transport == NCACN_IP_TCP ||
|
||||
cli->transport->transport == NCALRPC) {
|
||||
rpccli_close_sock_fd(cli);
|
||||
}
|
||||
|
||||
if (cli->transport->transport == NCACN_NP) {
|
||||
rpccli_close_np_fd(cli);
|
||||
}
|
||||
}
|
||||
fail:
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
|
@ -402,3 +402,15 @@ struct cli_state *rpc_pipe_np_smb_conn(struct rpc_pipe_client *p)
|
||||
}
|
||||
return state->cli;
|
||||
}
|
||||
|
||||
void rpccli_close_np_fd(struct rpc_pipe_client *p)
|
||||
{
|
||||
struct cli_state *cli = rpc_pipe_np_smb_conn(p);
|
||||
if (cli) {
|
||||
if (cli->fd != -1) {
|
||||
close(cli->fd);
|
||||
cli->fd = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
@ -682,3 +682,13 @@ NTSTATUS rpc_transport_smbd_init(TALLOC_CTX *mem_ctx,
|
||||
TALLOC_FREE(frame);
|
||||
return status;
|
||||
}
|
||||
|
||||
struct cli_state *rpc_pipe_smbd_smb_conn(struct rpc_pipe_client *p)
|
||||
{
|
||||
struct rpc_transport_smbd_state *state = talloc_get_type(p->transport->priv,
|
||||
struct rpc_transport_smbd_state);
|
||||
if (!state || !state->conn) {
|
||||
return NULL;
|
||||
}
|
||||
return state->conn->cli;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
struct rpc_transport_sock_state {
|
||||
int fd;
|
||||
int timeout;
|
||||
};
|
||||
|
||||
static int rpc_transport_sock_state_destructor(struct rpc_transport_sock_state *s)
|
||||
@ -51,6 +52,7 @@ static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
|
||||
priv, struct rpc_transport_sock_state);
|
||||
struct tevent_req *req, *subreq;
|
||||
struct rpc_sock_read_state *state;
|
||||
struct timeval endtime;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct rpc_sock_read_state);
|
||||
if (req == NULL) {
|
||||
@ -61,10 +63,16 @@ static struct tevent_req *rpc_sock_read_send(TALLOC_CTX *mem_ctx,
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
state->transp = sock_transp;
|
||||
endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);
|
||||
subreq = async_recv_send(state, ev, sock_transp->fd, data, size, 0);
|
||||
if (subreq == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!tevent_req_set_endtime(subreq, ev, endtime)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, rpc_sock_read_done, req);
|
||||
return req;
|
||||
fail:
|
||||
@ -121,6 +129,7 @@ static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
|
||||
priv, struct rpc_transport_sock_state);
|
||||
struct tevent_req *req, *subreq;
|
||||
struct rpc_sock_write_state *state;
|
||||
struct timeval endtime;
|
||||
|
||||
req = tevent_req_create(mem_ctx, &state, struct rpc_sock_write_state);
|
||||
if (req == NULL) {
|
||||
@ -131,10 +140,16 @@ static struct tevent_req *rpc_sock_write_send(TALLOC_CTX *mem_ctx,
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
state->transp = sock_transp;
|
||||
endtime = timeval_current_ofs(0, sock_transp->timeout * 1000);
|
||||
subreq = async_send_send(state, ev, sock_transp->fd, data, size, 0);
|
||||
if (subreq == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!tevent_req_set_endtime(subreq, ev, endtime)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
tevent_req_set_callback(subreq, rpc_sock_write_done, req);
|
||||
return req;
|
||||
fail:
|
||||
@ -193,6 +208,7 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
|
||||
result->priv = state;
|
||||
|
||||
state->fd = fd;
|
||||
state->timeout = 10000; /* 10 seconds. */
|
||||
talloc_set_destructor(state, rpc_transport_sock_state_destructor);
|
||||
|
||||
result->trans_send = NULL;
|
||||
@ -205,3 +221,40 @@ NTSTATUS rpc_transport_sock_init(TALLOC_CTX *mem_ctx, int fd,
|
||||
*presult = result;
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
int rpccli_set_sock_timeout(struct rpc_pipe_client *cli, int timeout)
|
||||
{
|
||||
struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv,
|
||||
struct rpc_transport_sock_state);
|
||||
int orig_timeout;
|
||||
if (!state) {
|
||||
return 0;
|
||||
}
|
||||
orig_timeout = state->timeout;
|
||||
state->timeout = timeout;
|
||||
return orig_timeout;
|
||||
}
|
||||
|
||||
void rpccli_close_sock_fd(struct rpc_pipe_client *cli)
|
||||
{
|
||||
struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv,
|
||||
struct rpc_transport_sock_state);
|
||||
if (state) {
|
||||
if (state->fd != -1) {
|
||||
close(state->fd);
|
||||
state->fd = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool rpc_pipe_tcp_connection_ok(struct rpc_pipe_client *cli)
|
||||
{
|
||||
struct rpc_transport_sock_state *state = talloc_get_type(cli->transport->priv,
|
||||
struct rpc_transport_sock_state);
|
||||
if (state && state->fd != -1) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -903,6 +903,13 @@ static ssize_t read_from_internal_pipe(struct pipes_struct *p, char *data, size_
|
||||
out:
|
||||
(*is_data_outstanding) = prs_offset(&p->out_data.frag) > n;
|
||||
|
||||
if (p->out_data.current_pdu_sent == prs_offset(&p->out_data.frag)) {
|
||||
/* We've returned everything in the out_data.frag
|
||||
* so we're done with this pdu. Free it and reset
|
||||
* current_pdu_sent. */
|
||||
p->out_data.current_pdu_sent = 0;
|
||||
prs_mem_free(&p->out_data.frag);
|
||||
}
|
||||
return data_returned;
|
||||
}
|
||||
|
||||
|
@ -353,6 +353,11 @@ static void pipe_write_andx_done(struct tevent_req *subreq)
|
||||
|
||||
done:
|
||||
chain_reply(req);
|
||||
/*
|
||||
* We must free here as the ownership of req was
|
||||
* moved to the connection struct in reply_pipe_write_and_X().
|
||||
*/
|
||||
TALLOC_FREE(req);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -458,4 +463,9 @@ static void pipe_read_andx_done(struct tevent_req *subreq)
|
||||
|
||||
done:
|
||||
chain_reply(req);
|
||||
/*
|
||||
* We must free here as the ownership of req was
|
||||
* moved to the connection struct in reply_pipe_read_and_X().
|
||||
*/
|
||||
TALLOC_FREE(req);
|
||||
}
|
||||
|
@ -37,10 +37,10 @@ static int net_usage(struct net_context *c, int argc, const char **argv)
|
||||
for (i=0; table[i].funcname != NULL; i++) {
|
||||
if (c->display_usage) {
|
||||
d_printf(_("net %s usage:\n"), table[i].funcname);
|
||||
d_printf("\n%s\n\n", table[i].usage);
|
||||
d_printf("\n%s\n\n", _(table[i].usage));
|
||||
} else {
|
||||
d_printf("%s %-15s %s\n", "net", table[i].funcname,
|
||||
table[i].description);
|
||||
_(table[i].description));
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -583,13 +583,13 @@ int net_run_function(struct net_context *c, int argc, const char **argv,
|
||||
d_fprintf(stderr, _("Invalid command: %s %s\n"), whoami,
|
||||
(argc > 0)?argv[0]:"");
|
||||
}
|
||||
d_printf("Usage:\n");
|
||||
d_printf(_("Usage:\n"));
|
||||
for (i=0; table[i].funcname != NULL; i++) {
|
||||
if(c->display_usage == false)
|
||||
d_printf("%s %-15s %s\n", whoami, table[i].funcname,
|
||||
table[i].description);
|
||||
_(table[i].description));
|
||||
else
|
||||
d_printf("%s\n", table[i].usage);
|
||||
d_printf("%s\n", _(table[i].usage));
|
||||
}
|
||||
|
||||
return c->display_usage?0:-1;
|
||||
@ -599,7 +599,7 @@ void net_display_usage_from_functable(struct functable *table)
|
||||
{
|
||||
int i;
|
||||
for (i=0; table[i].funcname != NULL; i++) {
|
||||
d_printf("%s\n", table[i].usage);
|
||||
d_printf("%s\n", _(table[i].usage));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1380,6 +1380,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
|
||||
struct cache_entry *centry = NULL;
|
||||
NTSTATUS status;
|
||||
unsigned int i, retry;
|
||||
bool old_status = domain->online;
|
||||
|
||||
if (!cache->tdb)
|
||||
goto do_query;
|
||||
@ -1388,6 +1389,7 @@ static NTSTATUS query_user_list(struct winbindd_domain *domain,
|
||||
if (!centry)
|
||||
goto do_query;
|
||||
|
||||
do_fetch_cache:
|
||||
*num_entries = centry_uint32(centry);
|
||||
|
||||
if (*num_entries == 0)
|
||||
@ -1448,12 +1450,44 @@ do_query:
|
||||
"connection cache\n"));
|
||||
invalidate_cm_connection(&domain->conn);
|
||||
}
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
/* store partial response. */
|
||||
if (*num_entries > 0) {
|
||||
/*
|
||||
* humm, what about the status used for cache?
|
||||
* Should it be NT_STATUS_OK?
|
||||
*/
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* domain is offline now, and there is no user entries,
|
||||
* try to fetch from cache again.
|
||||
*/
|
||||
if (cache->tdb && !domain->online && !domain->internal && old_status) {
|
||||
centry = wcache_fetch(cache, domain, "UL/%s", domain->name);
|
||||
/* partial response... */
|
||||
if (!centry) {
|
||||
goto skip_save;
|
||||
} else {
|
||||
goto do_fetch_cache;
|
||||
}
|
||||
} else {
|
||||
goto skip_save;
|
||||
}
|
||||
}
|
||||
|
||||
} while (NT_STATUS_V(status) == NT_STATUS_V(NT_STATUS_UNSUCCESSFUL) &&
|
||||
(retry++ < 5));
|
||||
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
goto skip_save;
|
||||
@ -1497,7 +1531,9 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
|
||||
struct cache_entry *centry = NULL;
|
||||
NTSTATUS status;
|
||||
unsigned int i;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
if (!cache->tdb)
|
||||
goto do_query;
|
||||
|
||||
@ -1505,6 +1541,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
|
||||
if (!centry)
|
||||
goto do_query;
|
||||
|
||||
do_fetch_cache:
|
||||
*num_entries = centry_uint32(centry);
|
||||
|
||||
if (*num_entries == 0)
|
||||
@ -1543,8 +1580,26 @@ do_query:
|
||||
|
||||
status = domain->backend->enum_dom_groups(domain, mem_ctx, num_entries, info);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (cache->tdb &&
|
||||
!domain->online &&
|
||||
!domain->internal &&
|
||||
old_status) {
|
||||
centry = wcache_fetch(cache, domain, "GL/%s/domain", domain->name);
|
||||
if (centry) {
|
||||
goto do_fetch_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
goto skip_save;
|
||||
@ -1571,7 +1626,9 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
struct cache_entry *centry = NULL;
|
||||
NTSTATUS status;
|
||||
unsigned int i;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
if (!cache->tdb)
|
||||
goto do_query;
|
||||
|
||||
@ -1579,6 +1636,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
if (!centry)
|
||||
goto do_query;
|
||||
|
||||
do_fetch_cache:
|
||||
*num_entries = centry_uint32(centry);
|
||||
|
||||
if (*num_entries == 0)
|
||||
@ -1627,8 +1685,26 @@ do_query:
|
||||
|
||||
status = domain->backend->enum_local_groups(domain, mem_ctx, num_entries, info);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (cache->tdb &&
|
||||
!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
centry = wcache_fetch(cache, domain, "GL/%s/local", domain->name);
|
||||
if (centry) {
|
||||
goto do_fetch_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
goto skip_save;
|
||||
@ -1694,6 +1770,9 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
enum lsa_SidType *type)
|
||||
{
|
||||
NTSTATUS status;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
|
||||
status = wcache_name_to_sid(domain, domain_name, name, sid, type);
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
@ -1719,6 +1798,19 @@ static NTSTATUS name_to_sid(struct winbindd_domain *domain,
|
||||
status = domain->backend->name_to_sid(domain, mem_ctx, domain_name,
|
||||
name, flags, sid, type);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
NTSTATUS cache_status;
|
||||
cache_status = wcache_name_to_sid(domain, domain_name, name, sid, type);
|
||||
return cache_status;
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
|
||||
@ -1789,7 +1881,9 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
enum lsa_SidType *type)
|
||||
{
|
||||
NTSTATUS status;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
status = wcache_sid_to_name(domain, sid, mem_ctx, domain_name, name,
|
||||
type);
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
@ -1815,8 +1909,25 @@ static NTSTATUS sid_to_name(struct winbindd_domain *domain,
|
||||
|
||||
status = domain->backend->sid_to_name(domain, mem_ctx, sid, domain_name, name, type);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
NTSTATUS cache_status;
|
||||
cache_status = wcache_sid_to_name(domain, sid, mem_ctx,
|
||||
domain_name, name, type);
|
||||
return cache_status;
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
wcache_save_sid_to_name(domain, status, sid, *domain_name, *name, *type);
|
||||
|
||||
/* We can't save the name to sid mapping here, as with sid history a
|
||||
@ -1839,7 +1950,9 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain,
|
||||
NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
|
||||
bool have_mapped;
|
||||
bool have_unmapped;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
*domain_name = NULL;
|
||||
*names = NULL;
|
||||
*types = NULL;
|
||||
@ -1924,6 +2037,73 @@ static NTSTATUS rids_to_names(struct winbindd_domain *domain,
|
||||
rids, num_rids, domain_name,
|
||||
names, types);
|
||||
|
||||
if (NT_STATUS_EQUAL(result, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (cache->tdb &&
|
||||
!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
have_mapped = have_unmapped = false;
|
||||
|
||||
for (i=0; i<num_rids; i++) {
|
||||
DOM_SID sid;
|
||||
struct cache_entry *centry;
|
||||
fstring tmp;
|
||||
|
||||
if (!sid_compose(&sid, domain_sid, rids[i])) {
|
||||
result = NT_STATUS_INTERNAL_ERROR;
|
||||
goto error;
|
||||
}
|
||||
|
||||
centry = wcache_fetch(cache, domain, "SN/%s",
|
||||
sid_to_fstring(tmp, &sid));
|
||||
if (!centry) {
|
||||
(*types)[i] = SID_NAME_UNKNOWN;
|
||||
(*names)[i] = talloc_strdup(*names, "");
|
||||
continue;
|
||||
}
|
||||
|
||||
(*types)[i] = SID_NAME_UNKNOWN;
|
||||
(*names)[i] = talloc_strdup(*names, "");
|
||||
|
||||
if (NT_STATUS_IS_OK(centry->status)) {
|
||||
char *dom;
|
||||
have_mapped = true;
|
||||
(*types)[i] = (enum lsa_SidType)centry_uint32(centry);
|
||||
|
||||
dom = centry_string(centry, mem_ctx);
|
||||
if (*domain_name == NULL) {
|
||||
*domain_name = dom;
|
||||
} else {
|
||||
talloc_free(dom);
|
||||
}
|
||||
|
||||
(*names)[i] = centry_string(centry, *names);
|
||||
|
||||
} else if (NT_STATUS_EQUAL(centry->status, NT_STATUS_NONE_MAPPED)) {
|
||||
have_unmapped = true;
|
||||
|
||||
} else {
|
||||
/* something's definitely wrong */
|
||||
result = centry->status;
|
||||
goto error;
|
||||
}
|
||||
|
||||
centry_free(centry);
|
||||
}
|
||||
|
||||
if (!have_mapped) {
|
||||
return NT_STATUS_NONE_MAPPED;
|
||||
}
|
||||
if (!have_unmapped) {
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
return STATUS_SOME_UNMAPPED;
|
||||
}
|
||||
}
|
||||
/*
|
||||
None of the queried rids has been found so save all negative entries
|
||||
*/
|
||||
@ -2046,7 +2226,9 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
|
||||
struct wbint_userinfo *info)
|
||||
{
|
||||
NTSTATUS status;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
status = wcache_query_user(domain, mem_ctx, user_sid, info);
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
return status;
|
||||
@ -2064,8 +2246,24 @@ static NTSTATUS query_user(struct winbindd_domain *domain,
|
||||
|
||||
status = domain->backend->query_user(domain, mem_ctx, user_sid, info);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
NTSTATUS cache_status;
|
||||
cache_status = wcache_query_user(domain, mem_ctx, user_sid, info);
|
||||
return cache_status;
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
wcache_save_user(domain, status, info);
|
||||
|
||||
return status;
|
||||
@ -2140,7 +2338,9 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
|
||||
NTSTATUS status;
|
||||
unsigned int i;
|
||||
fstring sid_string;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
status = wcache_lookup_usergroups(domain, mem_ctx, user_sid,
|
||||
num_groups, user_gids);
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
@ -2160,11 +2360,28 @@ static NTSTATUS lookup_usergroups(struct winbindd_domain *domain,
|
||||
|
||||
status = domain->backend->lookup_usergroups(domain, mem_ctx, user_sid, num_groups, user_gids);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
NTSTATUS cache_status;
|
||||
cache_status = wcache_lookup_usergroups(domain, mem_ctx, user_sid,
|
||||
num_groups, user_gids);
|
||||
return cache_status;
|
||||
}
|
||||
}
|
||||
if ( NT_STATUS_EQUAL(status, NT_STATUS_SYNCHRONIZATION_REQUIRED) )
|
||||
goto skip_save;
|
||||
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
goto skip_save;
|
||||
@ -2272,7 +2489,9 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
|
||||
NTSTATUS status;
|
||||
char *sidlist;
|
||||
int i;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
status = wcache_lookup_useraliases(domain, mem_ctx, num_sids, sids,
|
||||
num_aliases, alias_rids);
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
@ -2297,8 +2516,25 @@ static NTSTATUS lookup_useraliases(struct winbindd_domain *domain,
|
||||
num_sids, sids,
|
||||
num_aliases, alias_rids);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
NTSTATUS cache_status;
|
||||
cache_status = wcache_lookup_useraliases(domain, mem_ctx, num_sids,
|
||||
sids, num_aliases, alias_rids);
|
||||
return cache_status;
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
goto skip_save;
|
||||
@ -2389,7 +2625,9 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
|
||||
NTSTATUS status;
|
||||
unsigned int i;
|
||||
fstring sid_string;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
status = wcache_lookup_groupmem(domain, mem_ctx, group_sid, num_names,
|
||||
sid_mem, names, name_types);
|
||||
if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
|
||||
@ -2413,8 +2651,26 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
|
||||
type, num_names,
|
||||
sid_mem, names, name_types);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
NTSTATUS cache_status;
|
||||
cache_status = wcache_lookup_groupmem(domain, mem_ctx, group_sid,
|
||||
num_names, sid_mem, names,
|
||||
name_types);
|
||||
return cache_status;
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
centry = centry_start(domain, status);
|
||||
if (!centry)
|
||||
goto skip_save;
|
||||
@ -2449,7 +2705,71 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
struct netr_DomainTrustList *trusts)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct winbind_cache *cache;
|
||||
struct winbindd_tdc_domain *dom_list = NULL;
|
||||
size_t num_domains = 0;
|
||||
bool retval = false;
|
||||
int i;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
trusts->count = 0;
|
||||
trusts->array = NULL;
|
||||
if (domain->online) {
|
||||
goto do_query;
|
||||
}
|
||||
|
||||
cache = get_cache(domain);
|
||||
if (!cache || !cache->tdb) {
|
||||
goto do_query;
|
||||
}
|
||||
|
||||
retval = wcache_tdc_fetch_list(&dom_list, &num_domains);
|
||||
if (!retval || !num_domains || !dom_list) {
|
||||
TALLOC_FREE(dom_list);
|
||||
goto do_query;
|
||||
}
|
||||
|
||||
do_fetch_cache:
|
||||
trusts->array = TALLOC_ZERO_ARRAY(mem_ctx, struct netr_DomainTrust, num_domains);
|
||||
if (!trusts->array) {
|
||||
TALLOC_FREE(dom_list);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_domains; i++) {
|
||||
struct netr_DomainTrust *trust;
|
||||
struct dom_sid *sid;
|
||||
struct winbindd_domain *dom;
|
||||
|
||||
dom = find_domain_from_name_noinit(dom_list[i].domain_name);
|
||||
if (dom && dom->internal) {
|
||||
continue;
|
||||
}
|
||||
|
||||
trust = &trusts->array[trusts->count];
|
||||
trust->netbios_name = talloc_strdup(trusts->array, dom_list[i].domain_name);
|
||||
trust->dns_name = talloc_strdup(trusts->array, dom_list[i].dns_name);
|
||||
sid = talloc(trusts->array, struct dom_sid);
|
||||
if (!trust->netbios_name || !trust->dns_name ||
|
||||
!sid) {
|
||||
TALLOC_FREE(dom_list);
|
||||
TALLOC_FREE(trusts->array);
|
||||
return NT_STATUS_NO_MEMORY;
|
||||
}
|
||||
|
||||
trust->trust_flags = dom_list[i].trust_flags;
|
||||
trust->trust_attributes = dom_list[i].trust_attribs;
|
||||
trust->trust_type = dom_list[i].trust_type;
|
||||
sid_copy(sid, &dom_list[i].sid);
|
||||
trust->sid = sid;
|
||||
trusts->count++;
|
||||
}
|
||||
|
||||
TALLOC_FREE(dom_list);
|
||||
return NT_STATUS_OK;
|
||||
|
||||
do_query:
|
||||
/* Return status value returned by seq number check */
|
||||
|
||||
if (!NT_STATUS_IS_OK(domain->last_status))
|
||||
@ -2460,6 +2780,22 @@ static NTSTATUS trusted_domains(struct winbindd_domain *domain,
|
||||
|
||||
status = domain->backend->trusted_domains(domain, mem_ctx, trusts);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
retval = wcache_tdc_fetch_list(&dom_list, &num_domains);
|
||||
if (retval && num_domains && dom_list) {
|
||||
TALLOC_FREE(trusts->array);
|
||||
trusts->count = 0;
|
||||
goto do_fetch_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* no trusts gives NT_STATUS_NO_MORE_ENTRIES resetting to NT_STATUS_OK
|
||||
* so that the generic centry handling still applies correctly -
|
||||
* Guenther*/
|
||||
@ -2478,7 +2814,9 @@ static NTSTATUS lockout_policy(struct winbindd_domain *domain,
|
||||
struct winbind_cache *cache = get_cache(domain);
|
||||
struct cache_entry *centry = NULL;
|
||||
NTSTATUS status;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
if (!cache->tdb)
|
||||
goto do_query;
|
||||
|
||||
@ -2487,6 +2825,7 @@ static NTSTATUS lockout_policy(struct winbindd_domain *domain,
|
||||
if (!centry)
|
||||
goto do_query;
|
||||
|
||||
do_fetch_cache:
|
||||
policy->lockout_duration = centry_nttime(centry);
|
||||
policy->lockout_window = centry_nttime(centry);
|
||||
policy->lockout_threshold = centry_uint16(centry);
|
||||
@ -2512,8 +2851,26 @@ do_query:
|
||||
|
||||
status = domain->backend->lockout_policy(domain, mem_ctx, policy);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (cache->tdb &&
|
||||
!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
centry = wcache_fetch(cache, domain, "LOC_POL/%s", domain->name);
|
||||
if (centry) {
|
||||
goto do_fetch_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
wcache_save_lockout_policy(domain, status, policy);
|
||||
|
||||
return status;
|
||||
@ -2527,7 +2884,9 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
|
||||
struct winbind_cache *cache = get_cache(domain);
|
||||
struct cache_entry *centry = NULL;
|
||||
NTSTATUS status;
|
||||
bool old_status;
|
||||
|
||||
old_status = domain->online;
|
||||
if (!cache->tdb)
|
||||
goto do_query;
|
||||
|
||||
@ -2536,6 +2895,7 @@ static NTSTATUS password_policy(struct winbindd_domain *domain,
|
||||
if (!centry)
|
||||
goto do_query;
|
||||
|
||||
do_fetch_cache:
|
||||
policy->min_password_length = centry_uint16(centry);
|
||||
policy->password_history_length = centry_uint16(centry);
|
||||
policy->password_properties = centry_uint32(centry);
|
||||
@ -2563,11 +2923,27 @@ do_query:
|
||||
|
||||
status = domain->backend->password_policy(domain, mem_ctx, policy);
|
||||
|
||||
if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) ||
|
||||
NT_STATUS_EQUAL(status, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND)) {
|
||||
if (!domain->internal && old_status) {
|
||||
set_domain_offline(domain);
|
||||
}
|
||||
if (cache->tdb &&
|
||||
!domain->internal &&
|
||||
!domain->online &&
|
||||
old_status) {
|
||||
centry = wcache_fetch(cache, domain, "PWD_POL/%s", domain->name);
|
||||
if (centry) {
|
||||
goto do_fetch_cache;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* and save it */
|
||||
refresh_sequence_number(domain, false);
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
wcache_save_password_policy(domain, status, policy);
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
}
|
||||
wcache_save_password_policy(domain, status, policy);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2214,7 +2214,8 @@ NTSTATUS cm_connect_lsa_tcp(struct winbindd_domain *domain,
|
||||
|
||||
if (conn->lsa_pipe_tcp &&
|
||||
conn->lsa_pipe_tcp->transport->transport == NCACN_IP_TCP &&
|
||||
conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY) {
|
||||
conn->lsa_pipe_tcp->auth->auth_level == DCERPC_AUTH_LEVEL_PRIVACY &&
|
||||
rpc_pipe_tcp_connection_ok(conn->lsa_pipe_tcp)) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
@ -199,7 +199,7 @@ static NTSTATUS enum_dom_groups(struct winbindd_domain *domain,
|
||||
talloc_destroy(mem_ctx2);
|
||||
} while (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return status;
|
||||
}
|
||||
|
||||
/* List all domain groups */
|
||||
@ -269,7 +269,7 @@ static NTSTATUS enum_local_groups(struct winbindd_domain *domain,
|
||||
|
||||
} while (NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES));
|
||||
|
||||
return NT_STATUS_OK;
|
||||
return result;
|
||||
}
|
||||
|
||||
/* convert a single name to a sid in a domain */
|
||||
@ -1286,12 +1286,8 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
|
||||
* This call can take a long time
|
||||
* allow the server to time out.
|
||||
* 35 seconds should do it.
|
||||
* NB
|
||||
* only do this when the undelying transport is named pipe.
|
||||
*/
|
||||
if (cli->transport->transport == NCACN_NP) {
|
||||
orig_timeout = rpccli_set_timeout(cli, 35000);
|
||||
}
|
||||
|
||||
status = lookup_names_fn(cli,
|
||||
mem_ctx,
|
||||
@ -1304,9 +1300,7 @@ NTSTATUS winbindd_lookup_names(TALLOC_CTX *mem_ctx,
|
||||
types);
|
||||
|
||||
/* And restore our original timeout. */
|
||||
if (cli->transport->transport == NCACN_NP) {
|
||||
rpccli_set_timeout(cli, orig_timeout);
|
||||
}
|
||||
|
||||
if (!NT_STATUS_IS_OK(status)) {
|
||||
return status;
|
||||
|
@ -101,13 +101,14 @@ static void dreplsrv_op_notify_replica_sync_send(struct dreplsrv_op_notify_state
|
||||
/*
|
||||
called when we have an established connection
|
||||
*/
|
||||
static void dreplsrv_op_notify_connect_recv(struct composite_context *creq)
|
||||
static void dreplsrv_op_notify_connect_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct dreplsrv_op_notify_state *st = talloc_get_type(creq->async.private_data,
|
||||
struct dreplsrv_op_notify_state *st = tevent_req_callback_data(subreq,
|
||||
struct dreplsrv_op_notify_state);
|
||||
struct composite_context *c = st->creq;
|
||||
|
||||
c->status = dreplsrv_out_drsuapi_recv(creq);
|
||||
c->status = dreplsrv_out_drsuapi_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
dreplsrv_op_notify_replica_sync_send(st);
|
||||
@ -119,8 +120,8 @@ static void dreplsrv_op_notify_connect_recv(struct composite_context *creq)
|
||||
static struct composite_context *dreplsrv_op_notify_send(struct dreplsrv_notify_operation *op)
|
||||
{
|
||||
struct composite_context *c;
|
||||
struct composite_context *creq;
|
||||
struct dreplsrv_op_notify_state *st;
|
||||
struct tevent_req *subreq;
|
||||
|
||||
c = composite_create(op, op->service->task->event_ctx);
|
||||
if (c == NULL) return NULL;
|
||||
@ -131,8 +132,11 @@ static struct composite_context *dreplsrv_op_notify_send(struct dreplsrv_notify_
|
||||
st->creq = c;
|
||||
st->op = op;
|
||||
|
||||
creq = dreplsrv_out_drsuapi_send(op->source_dsa->conn);
|
||||
composite_continue(c, creq, dreplsrv_op_notify_connect_recv, st);
|
||||
subreq = dreplsrv_out_drsuapi_send(st,
|
||||
op->service->task->event_ctx,
|
||||
op->source_dsa->conn);
|
||||
if (composite_nomem(subreq, c)) return c;
|
||||
tevent_req_set_callback(subreq, dreplsrv_op_notify_connect_done, st);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
@ -34,10 +34,9 @@
|
||||
#include "libcli/composite/composite.h"
|
||||
#include "auth/gensec/gensec.h"
|
||||
#include "param/param.h"
|
||||
#include "../lib/util/tevent_ntstatus.h"
|
||||
|
||||
struct dreplsrv_out_drsuapi_state {
|
||||
struct composite_context *creq;
|
||||
|
||||
struct dreplsrv_out_connection *conn;
|
||||
|
||||
struct dreplsrv_drsuapi_connection *drsuapi;
|
||||
@ -46,139 +45,160 @@ struct dreplsrv_out_drsuapi_state {
|
||||
struct drsuapi_DsBind bind_r;
|
||||
};
|
||||
|
||||
static void dreplsrv_out_drsuapi_connect_recv(struct composite_context *creq);
|
||||
static void dreplsrv_out_drsuapi_connect_done(struct composite_context *creq);
|
||||
|
||||
struct composite_context *dreplsrv_out_drsuapi_send(struct dreplsrv_out_connection *conn)
|
||||
struct tevent_req *dreplsrv_out_drsuapi_send(TALLOC_CTX *mem_ctx,
|
||||
struct tevent_context *ev,
|
||||
struct dreplsrv_out_connection *conn)
|
||||
{
|
||||
struct composite_context *c;
|
||||
struct tevent_req *req;
|
||||
struct dreplsrv_out_drsuapi_state *state;
|
||||
struct composite_context *creq;
|
||||
struct dreplsrv_out_drsuapi_state *st;
|
||||
|
||||
c = composite_create(conn, conn->service->task->event_ctx);
|
||||
if (c == NULL) return NULL;
|
||||
req = tevent_req_create(mem_ctx, &state,
|
||||
struct dreplsrv_out_drsuapi_state);
|
||||
if (req == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
st = talloc_zero(c, struct dreplsrv_out_drsuapi_state);
|
||||
if (composite_nomem(st, c)) return c;
|
||||
state->conn = conn;
|
||||
state->drsuapi = conn->drsuapi;
|
||||
|
||||
c->private_data = st;
|
||||
if (state->drsuapi && !state->drsuapi->pipe->conn->dead) {
|
||||
tevent_req_done(req);
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
st->creq = c;
|
||||
st->conn = conn;
|
||||
st->drsuapi = conn->drsuapi;
|
||||
|
||||
if (st->drsuapi && !st->drsuapi->pipe->conn->dead) {
|
||||
composite_done(c);
|
||||
return c;
|
||||
} else if (st->drsuapi && st->drsuapi->pipe->conn->dead) {
|
||||
talloc_free(st->drsuapi);
|
||||
if (state->drsuapi && state->drsuapi->pipe->conn->dead) {
|
||||
talloc_free(state->drsuapi);
|
||||
conn->drsuapi = NULL;
|
||||
}
|
||||
|
||||
st->drsuapi = talloc_zero(st, struct dreplsrv_drsuapi_connection);
|
||||
if (composite_nomem(st->drsuapi, c)) return c;
|
||||
state->drsuapi = talloc_zero(state, struct dreplsrv_drsuapi_connection);
|
||||
if (tevent_req_nomem(state->drsuapi, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
|
||||
creq = dcerpc_pipe_connect_b_send(st, conn->binding, &ndr_table_drsuapi,
|
||||
creq = dcerpc_pipe_connect_b_send(state, conn->binding, &ndr_table_drsuapi,
|
||||
conn->service->system_session_info->credentials,
|
||||
c->event_ctx, conn->service->task->lp_ctx);
|
||||
composite_continue(c, creq, dreplsrv_out_drsuapi_connect_recv, st);
|
||||
ev, conn->service->task->lp_ctx);
|
||||
if (tevent_req_nomem(creq, req)) {
|
||||
return tevent_req_post(req, ev);
|
||||
}
|
||||
composite_continue(NULL, creq, dreplsrv_out_drsuapi_connect_done, req);
|
||||
|
||||
return c;
|
||||
return req;
|
||||
}
|
||||
|
||||
static void dreplsrv_out_drsuapi_bind_send(struct dreplsrv_out_drsuapi_state *st);
|
||||
static void dreplsrv_out_drsuapi_bind_done(struct rpc_request *rreq);
|
||||
|
||||
static void dreplsrv_out_drsuapi_connect_recv(struct composite_context *creq)
|
||||
static void dreplsrv_out_drsuapi_connect_done(struct composite_context *creq)
|
||||
{
|
||||
struct dreplsrv_out_drsuapi_state *st = talloc_get_type(creq->async.private_data,
|
||||
struct tevent_req *req = talloc_get_type(creq->async.private_data,
|
||||
struct tevent_req);
|
||||
struct dreplsrv_out_drsuapi_state *state = tevent_req_data(req,
|
||||
struct dreplsrv_out_drsuapi_state);
|
||||
struct composite_context *c = st->creq;
|
||||
NTSTATUS status;
|
||||
struct rpc_request *rreq;
|
||||
|
||||
c->status = dcerpc_pipe_connect_b_recv(creq, st->drsuapi, &st->drsuapi->pipe);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
c->status = gensec_session_key(st->drsuapi->pipe->conn->security_state.generic_state,
|
||||
&st->drsuapi->gensec_skey);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
dreplsrv_out_drsuapi_bind_send(st);
|
||||
}
|
||||
|
||||
static void dreplsrv_out_drsuapi_bind_recv(struct rpc_request *req);
|
||||
|
||||
static void dreplsrv_out_drsuapi_bind_send(struct dreplsrv_out_drsuapi_state *st)
|
||||
{
|
||||
struct composite_context *c = st->creq;
|
||||
struct rpc_request *req;
|
||||
|
||||
st->bind_info_ctr.length = 28;
|
||||
st->bind_info_ctr.info.info28 = st->conn->service->bind_info28;
|
||||
|
||||
st->bind_r.in.bind_guid = &st->conn->service->ntds_guid;
|
||||
st->bind_r.in.bind_info = &st->bind_info_ctr;
|
||||
st->bind_r.out.bind_handle = &st->drsuapi->bind_handle;
|
||||
|
||||
req = dcerpc_drsuapi_DsBind_send(st->drsuapi->pipe, st, &st->bind_r);
|
||||
composite_continue_rpc(c, req, dreplsrv_out_drsuapi_bind_recv, st);
|
||||
}
|
||||
|
||||
static void dreplsrv_out_drsuapi_bind_recv(struct rpc_request *req)
|
||||
{
|
||||
struct dreplsrv_out_drsuapi_state *st = talloc_get_type(req->async.private_data,
|
||||
struct dreplsrv_out_drsuapi_state);
|
||||
struct composite_context *c = st->creq;
|
||||
|
||||
c->status = dcerpc_ndr_request_recv(req);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
if (!W_ERROR_IS_OK(st->bind_r.out.result)) {
|
||||
composite_error(c, werror_to_ntstatus(st->bind_r.out.result));
|
||||
status = dcerpc_pipe_connect_b_recv(creq,
|
||||
state->drsuapi,
|
||||
&state->drsuapi->pipe);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(st->drsuapi->remote_info28);
|
||||
if (st->bind_r.out.bind_info) {
|
||||
switch (st->bind_r.out.bind_info->length) {
|
||||
status = gensec_session_key(state->drsuapi->pipe->conn->security_state.generic_state,
|
||||
&state->drsuapi->gensec_skey);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
state->bind_info_ctr.length = 28;
|
||||
state->bind_info_ctr.info.info28 = state->conn->service->bind_info28;
|
||||
|
||||
state->bind_r.in.bind_guid = &state->conn->service->ntds_guid;
|
||||
state->bind_r.in.bind_info = &state->bind_info_ctr;
|
||||
state->bind_r.out.bind_handle = &state->drsuapi->bind_handle;
|
||||
|
||||
rreq = dcerpc_drsuapi_DsBind_send(state->drsuapi->pipe,
|
||||
state,
|
||||
&state->bind_r);
|
||||
if (tevent_req_nomem(rreq, req)) {
|
||||
return;
|
||||
}
|
||||
composite_continue_rpc(NULL, rreq, dreplsrv_out_drsuapi_bind_done, req);
|
||||
}
|
||||
|
||||
static void dreplsrv_out_drsuapi_bind_done(struct rpc_request *rreq)
|
||||
{
|
||||
struct tevent_req *req = talloc_get_type(rreq->async.private_data,
|
||||
struct tevent_req);
|
||||
struct dreplsrv_out_drsuapi_state *state = tevent_req_data(req,
|
||||
struct dreplsrv_out_drsuapi_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = dcerpc_ndr_request_recv(rreq);
|
||||
if (tevent_req_nterror(req, status)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!W_ERROR_IS_OK(state->bind_r.out.result)) {
|
||||
status = werror_to_ntstatus(state->bind_r.out.result);
|
||||
tevent_req_nterror(req, status);
|
||||
return;
|
||||
}
|
||||
|
||||
ZERO_STRUCT(state->drsuapi->remote_info28);
|
||||
if (state->bind_r.out.bind_info) {
|
||||
struct drsuapi_DsBindInfo28 *info28;
|
||||
info28 = &state->drsuapi->remote_info28;
|
||||
|
||||
switch (state->bind_r.out.bind_info->length) {
|
||||
case 24: {
|
||||
struct drsuapi_DsBindInfo24 *info24;
|
||||
info24 = &st->bind_r.out.bind_info->info.info24;
|
||||
st->drsuapi->remote_info28.supported_extensions = info24->supported_extensions;
|
||||
st->drsuapi->remote_info28.site_guid = info24->site_guid;
|
||||
st->drsuapi->remote_info28.pid = info24->pid;
|
||||
st->drsuapi->remote_info28.repl_epoch = 0;
|
||||
info24 = &state->bind_r.out.bind_info->info.info24;
|
||||
|
||||
info28->supported_extensions = info24->supported_extensions;
|
||||
info28->site_guid = info24->site_guid;
|
||||
info28->pid = info24->pid;
|
||||
info28->repl_epoch = 0;
|
||||
break;
|
||||
}
|
||||
case 48: {
|
||||
struct drsuapi_DsBindInfo48 *info48;
|
||||
info48 = &st->bind_r.out.bind_info->info.info48;
|
||||
st->drsuapi->remote_info28.supported_extensions = info48->supported_extensions;
|
||||
st->drsuapi->remote_info28.site_guid = info48->site_guid;
|
||||
st->drsuapi->remote_info28.pid = info48->pid;
|
||||
st->drsuapi->remote_info28.repl_epoch = info48->repl_epoch;
|
||||
info48 = &state->bind_r.out.bind_info->info.info48;
|
||||
|
||||
info28->supported_extensions = info48->supported_extensions;
|
||||
info28->site_guid = info48->site_guid;
|
||||
info28->pid = info48->pid;
|
||||
info28->repl_epoch = info48->repl_epoch;
|
||||
break;
|
||||
}
|
||||
case 28:
|
||||
st->drsuapi->remote_info28 = st->bind_r.out.bind_info->info.info28;
|
||||
*info28 = state->bind_r.out.bind_info->info.info28;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
composite_done(c);
|
||||
tevent_req_done(req);
|
||||
}
|
||||
|
||||
NTSTATUS dreplsrv_out_drsuapi_recv(struct composite_context *c)
|
||||
NTSTATUS dreplsrv_out_drsuapi_recv(struct tevent_req *req)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct dreplsrv_out_drsuapi_state *st = talloc_get_type(c->private_data,
|
||||
struct dreplsrv_out_drsuapi_state *state = tevent_req_data(req,
|
||||
struct dreplsrv_out_drsuapi_state);
|
||||
NTSTATUS status;
|
||||
|
||||
status = composite_wait(c);
|
||||
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
st->conn->drsuapi = talloc_steal(st->conn, st->drsuapi);
|
||||
if (tevent_req_is_nterror(req, &status)) {
|
||||
tevent_req_received(req);
|
||||
return status;
|
||||
}
|
||||
|
||||
talloc_free(c);
|
||||
return status;
|
||||
state->conn->drsuapi = talloc_move(state->conn, &state->drsuapi);
|
||||
|
||||
tevent_req_received(req);
|
||||
return NT_STATUS_OK;
|
||||
}
|
||||
|
||||
struct dreplsrv_op_pull_source_state {
|
||||
@ -195,13 +215,13 @@ struct dreplsrv_op_pull_source_state {
|
||||
struct drsuapi_DsGetNCChangesCtr6 *ctr6;
|
||||
};
|
||||
|
||||
static void dreplsrv_op_pull_source_connect_recv(struct composite_context *creq);
|
||||
static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq);
|
||||
|
||||
struct composite_context *dreplsrv_op_pull_source_send(struct dreplsrv_out_operation *op)
|
||||
{
|
||||
struct composite_context *c;
|
||||
struct composite_context *creq;
|
||||
struct dreplsrv_op_pull_source_state *st;
|
||||
struct tevent_req *subreq;
|
||||
|
||||
c = composite_create(op, op->service->task->event_ctx);
|
||||
if (c == NULL) return NULL;
|
||||
@ -212,21 +232,25 @@ struct composite_context *dreplsrv_op_pull_source_send(struct dreplsrv_out_opera
|
||||
st->creq = c;
|
||||
st->op = op;
|
||||
|
||||
creq = dreplsrv_out_drsuapi_send(op->source_dsa->conn);
|
||||
composite_continue(c, creq, dreplsrv_op_pull_source_connect_recv, st);
|
||||
subreq = dreplsrv_out_drsuapi_send(st,
|
||||
op->service->task->event_ctx,
|
||||
op->source_dsa->conn);
|
||||
if (composite_nomem(subreq, c)) return c;
|
||||
tevent_req_set_callback(subreq, dreplsrv_op_pull_source_connect_done, st);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static void dreplsrv_op_pull_source_get_changes_send(struct dreplsrv_op_pull_source_state *st);
|
||||
|
||||
static void dreplsrv_op_pull_source_connect_recv(struct composite_context *creq)
|
||||
static void dreplsrv_op_pull_source_connect_done(struct tevent_req *subreq)
|
||||
{
|
||||
struct dreplsrv_op_pull_source_state *st = talloc_get_type(creq->async.private_data,
|
||||
struct dreplsrv_op_pull_source_state *st = tevent_req_callback_data(subreq,
|
||||
struct dreplsrv_op_pull_source_state);
|
||||
struct composite_context *c = st->creq;
|
||||
|
||||
c->status = dreplsrv_out_drsuapi_recv(creq);
|
||||
c->status = dreplsrv_out_drsuapi_recv(subreq);
|
||||
TALLOC_FREE(subreq);
|
||||
if (!composite_is_ok(c)) return;
|
||||
|
||||
dreplsrv_op_pull_source_get_changes_send(st);
|
||||
|
@ -918,36 +918,33 @@ done:
|
||||
|
||||
static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
|
||||
{
|
||||
int ret;
|
||||
if (ac->dn) {
|
||||
struct ldb_request *req;
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_message *msg = ldb_msg_new(ac);
|
||||
|
||||
msg->dn = ac->dn;
|
||||
|
||||
ldb_msg_add_empty(msg, "defaultObjectCategory", LDB_FLAG_MOD_REPLACE, NULL);
|
||||
|
||||
ldb_msg_add_steal_string(msg, "defaultObjectCategory", ldb_dn_alloc_linearized(msg, ac->dn));
|
||||
struct ldb_message *msg;
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
|
||||
ldb = ldb_module_get_ctx(ac->module);
|
||||
|
||||
/* (Re)set the default object category to have it set to the DN in the
|
||||
* storage format */
|
||||
msg = ldb_msg_new(ac);
|
||||
msg->dn = ac->msg->dn;
|
||||
ldb_msg_add_empty(msg, "defaultObjectCategory",
|
||||
LDB_FLAG_MOD_REPLACE, NULL);
|
||||
ldb_msg_add_steal_string(msg, "defaultObjectCategory",
|
||||
ldb_dn_alloc_linearized(msg, ac->dn));
|
||||
|
||||
ret = ldb_build_mod_req(&req, ldb, ac,
|
||||
msg, NULL,
|
||||
ac, samldb_set_defaultObjectCategory_callback,
|
||||
ac,
|
||||
samldb_set_defaultObjectCategory_callback,
|
||||
ac->req);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(msg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ldb_next_request(ac->module, req);
|
||||
}
|
||||
|
||||
ret = samldb_next_step(ac);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ldb_module_done(ac->req, NULL, NULL, ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -957,12 +954,33 @@ static int samldb_set_defaultObjectCategory(struct samldb_ctx *ac)
|
||||
static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request *req,
|
||||
struct ldb_reply *ares)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct samldb_ctx *ac;
|
||||
int ret;
|
||||
|
||||
ac = talloc_get_type(req->context, struct samldb_ctx);
|
||||
ldb = ldb_module_get_ctx(ac->module);
|
||||
|
||||
if (!ares) {
|
||||
ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
goto done;
|
||||
}
|
||||
if (ares->error != LDB_SUCCESS) {
|
||||
if (ares->error == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
if (ldb_request_get_control(ac->req,
|
||||
LDB_CONTROL_RELAX_OID) != NULL) {
|
||||
/* Don't be pricky when the DN doesn't exist */
|
||||
/* if we have the RELAX control specified */
|
||||
ac->dn = req->op.search.base;
|
||||
return samldb_next_step(ac);
|
||||
} else {
|
||||
ldb_set_errstring(ldb,
|
||||
"samldb_find_defaultObjectCategory: "
|
||||
"Invalid DN for 'defaultObjectCategory'!");
|
||||
ares->error = LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
}
|
||||
|
||||
return ldb_module_done(ac->req, ares->controls,
|
||||
ares->response, ares->error);
|
||||
}
|
||||
@ -970,22 +988,33 @@ static int samldb_find_for_defaultObjectCategory_callback(struct ldb_request *re
|
||||
switch (ares->type) {
|
||||
case LDB_REPLY_ENTRY:
|
||||
ac->dn = talloc_steal(ac, ares->message->dn);
|
||||
|
||||
ret = LDB_SUCCESS;
|
||||
break;
|
||||
|
||||
case LDB_REPLY_REFERRAL:
|
||||
/* this should not happen */
|
||||
return ldb_module_done(ac->req, NULL, NULL,
|
||||
LDB_ERR_OPERATIONS_ERROR);
|
||||
talloc_free(ares);
|
||||
ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
break;
|
||||
|
||||
case LDB_REPLY_DONE:
|
||||
/* found or not found, go on */
|
||||
talloc_free(ares);
|
||||
|
||||
if (ac->dn != NULL) {
|
||||
/* when found go on */
|
||||
ret = samldb_next_step(ac);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ldb_module_done(ac->req, NULL, NULL, ret);
|
||||
} else {
|
||||
ret = LDB_ERR_OPERATIONS_ERROR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
done:
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ldb_module_done(ac->req, NULL, NULL, ret);
|
||||
}
|
||||
|
||||
return LDB_SUCCESS;
|
||||
}
|
||||
|
||||
@ -993,16 +1022,39 @@ static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
|
||||
{
|
||||
struct ldb_context *ldb;
|
||||
struct ldb_request *req;
|
||||
int ret;
|
||||
static const char *no_attrs[] = { NULL };
|
||||
int ret;
|
||||
const struct ldb_val *val;
|
||||
struct ldb_dn *def_obj_cat_dn;
|
||||
|
||||
ldb = ldb_module_get_ctx(ac->module);
|
||||
|
||||
ac->dn = NULL;
|
||||
|
||||
if (ldb_msg_find_element(ac->msg, "defaultObjectCategory") == NULL) {
|
||||
val = ldb_msg_find_ldb_val(ac->msg, "defaultObjectCategory");
|
||||
if (val != NULL) {
|
||||
/* "defaultObjectCategory" has been set by the caller. Do some
|
||||
* checks for consistency.
|
||||
* NOTE: The real constraint check (that 'defaultObjectCategory'
|
||||
* is the DN of the new objectclass or any parent of it) is
|
||||
* still incomplete.
|
||||
* For now we say that 'defaultObjectCategory' is valid if it
|
||||
* exists and it is of objectclass "classSchema". */
|
||||
def_obj_cat_dn = ldb_dn_from_ldb_val(ac, ldb, val);
|
||||
if (def_obj_cat_dn == NULL) {
|
||||
ldb_set_errstring(ldb,
|
||||
"samldb_find_defaultObjectCategory: Invalid DN "
|
||||
"for 'defaultObjectCategory'!");
|
||||
return LDB_ERR_CONSTRAINT_VIOLATION;
|
||||
}
|
||||
} else {
|
||||
/* "defaultObjectCategory" has not been set by the caller. Use
|
||||
* the entry DN for it. */
|
||||
def_obj_cat_dn = ac->msg->dn;
|
||||
}
|
||||
|
||||
ret = ldb_build_search_req(&req, ldb, ac,
|
||||
ac->msg->dn, LDB_SCOPE_BASE,
|
||||
def_obj_cat_dn, LDB_SCOPE_BASE,
|
||||
"objectClass=classSchema", no_attrs,
|
||||
NULL,
|
||||
ac, samldb_find_for_defaultObjectCategory_callback,
|
||||
@ -1010,23 +1062,17 @@ static int samldb_find_for_defaultObjectCategory(struct samldb_ctx *ac)
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
ret = dsdb_request_add_controls(ac->module, req, DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT);
|
||||
|
||||
ret = dsdb_request_add_controls(ac->module, req,
|
||||
DSDB_SEARCH_SHOW_DN_IN_STORAGE_FORMAT);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ldb_next_request(ac->module, req);
|
||||
}
|
||||
|
||||
ret = samldb_next_step(ac);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
return ldb_module_done(ac->req, NULL, NULL, ret);
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* samldb_add_entry (async)
|
||||
*/
|
||||
|
@ -102,7 +102,7 @@ static int dsdb_schema_from_schema_dn(TALLOC_CTX *mem_ctx, struct ldb_module *mo
|
||||
"(objectClass=classSchema)");
|
||||
if (ret != LDB_SUCCESS) {
|
||||
ldb_asprintf_errstring(ldb,
|
||||
"dsdb_schema: failed to search attributeSchema objects: %s",
|
||||
"dsdb_schema: failed to search classSchema objects: %s",
|
||||
ldb_errstring(ldb));
|
||||
goto failed;
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ ldb_asq_OBJ_FILES = $(ldbsrcdir)/modules/asq.o
|
||||
PRIVATE_DEPENDENCIES = LIBTALLOC LIBTEVENT
|
||||
CFLAGS = -I$(ldbsrcdir)/include
|
||||
INIT_FUNCTION = LDB_MODULE(sample)
|
||||
SUBSYSTEM = LIBTESTLDB
|
||||
SUBSYSTEM = LIBLDB
|
||||
|
||||
# End MODULE sample_module
|
||||
################################################
|
||||
|
@ -132,9 +132,41 @@ systemOnly: FALSE
|
||||
"""
|
||||
self.ldb.add_ldif(ldif)
|
||||
|
||||
# Search for created attribute
|
||||
res = []
|
||||
res = self.ldb.search("cn=%s,%s" % (attr_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
|
||||
self.assertEquals(len(res), 1)
|
||||
self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_display_name)
|
||||
self.assertTrue("schemaIDGUID" in res[0])
|
||||
|
||||
class_name = "test-Class" + time.strftime("%s", time.gmtime())
|
||||
class_ldap_display_name = class_name.replace("-", "")
|
||||
|
||||
# First try to create a class with a wrong "defaultObjectCategory"
|
||||
ldif = """
|
||||
dn: CN=%s,%s""" % (class_name, self.schema_dn) + """
|
||||
objectClass: top
|
||||
objectClass: classSchema
|
||||
defaultObjectCategory: CN=_
|
||||
adminDescription: """ + class_name + """
|
||||
adminDisplayName: """ + class_name + """
|
||||
cn: """ + class_name + """
|
||||
governsId: 1.2.840.""" + str(random.randint(1,100000)) + """.1.5.9939
|
||||
instanceType: 4
|
||||
objectClassCategory: 1
|
||||
subClassOf: organizationalPerson
|
||||
systemFlags: 16
|
||||
rDNAttID: cn
|
||||
systemMustContain: cn
|
||||
systemMustContain: """ + attr_ldap_display_name + """
|
||||
systemOnly: FALSE
|
||||
"""
|
||||
try:
|
||||
self.ldb.add_ldif(ldif)
|
||||
self.fail()
|
||||
except LdbError, (num, _):
|
||||
self.assertEquals(num, ERR_CONSTRAINT_VIOLATION)
|
||||
|
||||
ldif = """
|
||||
dn: CN=%s,%s""" % (class_name, self.schema_dn) + """
|
||||
objectClass: top
|
||||
@ -154,6 +186,14 @@ systemOnly: FALSE
|
||||
"""
|
||||
self.ldb.add_ldif(ldif)
|
||||
|
||||
# Search for created objectclass
|
||||
res = []
|
||||
res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
|
||||
self.assertEquals(len(res), 1)
|
||||
self.assertEquals(res[0]["lDAPDisplayName"][0], class_ldap_display_name)
|
||||
self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0])
|
||||
self.assertTrue("schemaIDGUID" in res[0])
|
||||
|
||||
ldif = """
|
||||
dn:
|
||||
changetype: modify
|
||||
@ -179,21 +219,6 @@ name: """ + object_name + """
|
||||
"""
|
||||
self.ldb.add_ldif(ldif)
|
||||
|
||||
# Search for created attribute
|
||||
res = []
|
||||
res = self.ldb.search("cn=%s,%s" % (attr_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
|
||||
self.assertEquals(len(res), 1)
|
||||
self.assertEquals(res[0]["lDAPDisplayName"][0], attr_ldap_display_name)
|
||||
self.assertTrue("schemaIDGUID" in res[0])
|
||||
|
||||
# Search for created objectclass
|
||||
res = []
|
||||
res = self.ldb.search("cn=%s,%s" % (class_name, self.schema_dn), scope=SCOPE_BASE, attrs=["*"])
|
||||
self.assertEquals(len(res), 1)
|
||||
self.assertEquals(res[0]["lDAPDisplayName"][0], class_ldap_display_name)
|
||||
self.assertEquals(res[0]["defaultObjectCategory"][0], res[0]["distinguishedName"][0])
|
||||
self.assertTrue("schemaIDGUID" in res[0])
|
||||
|
||||
# Search for created object
|
||||
res = []
|
||||
res = self.ldb.search("cn=%s,cn=Users,%s" % (object_name, self.base_dn), scope=SCOPE_BASE, attrs=["*"])
|
||||
|
@ -283,14 +283,19 @@ static void run_child_getaddrinfo(struct dns_ex_state *state, int fd)
|
||||
hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV;
|
||||
|
||||
ret = getaddrinfo(state->name.name, "0", &hints, &res_list);
|
||||
/* try to fallback in case of error */
|
||||
if (state->do_fallback) {
|
||||
switch (ret) {
|
||||
#ifdef EAI_NODATA
|
||||
if (ret == EAI_NODATA && state->do_fallback) {
|
||||
#else
|
||||
if (ret == EAI_NONAME && state->do_fallback) {
|
||||
case EAI_NODATA:
|
||||
#endif
|
||||
case EAI_NONAME:
|
||||
/* getaddrinfo() doesn't handle CNAME records */
|
||||
run_child_dns_lookup(state, fd);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret != 0) {
|
||||
goto done;
|
||||
|
@ -643,10 +643,104 @@ static bool test_async(struct torture_context *tctx,
|
||||
/* cleanup the second lock */
|
||||
io.lockx.in.ulock_cnt = 1;
|
||||
io.lockx.in.lock_cnt = 0;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = &lock[1];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
/* If a lock request contained multiple ranges and we are cancelling
|
||||
* one while it's still pending, what happens? */
|
||||
torture_comment(tctx, "testing cancel 1/2 lock request\n");
|
||||
|
||||
/* Send request with two ranges */
|
||||
io.lockx.in.timeout = -1;
|
||||
io.lockx.in.ulock_cnt = 0;
|
||||
io.lockx.in.lock_cnt = 2;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = lock;
|
||||
req = smb_raw_lock_send(cli->tree, &io);
|
||||
torture_assert(tctx,(req != NULL), talloc_asprintf(tctx,
|
||||
"Failed to setup pending lock (%s)\n", __location__));
|
||||
|
||||
/* Try to cancel the first lock range */
|
||||
io.lockx.in.timeout = 0;
|
||||
io.lockx.in.lock_cnt = 1;
|
||||
io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = &lock[0];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
/* Locking request should've failed and second range should be
|
||||
* unlocked */
|
||||
status = smbcli_request_simple_recv(req);
|
||||
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
|
||||
|
||||
io.lockx.in.timeout = 0;
|
||||
io.lockx.in.ulock_cnt = 0;
|
||||
io.lockx.in.lock_cnt = 1;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = &lock[1];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
/* Cleanup both locks */
|
||||
io.lockx.in.ulock_cnt = 2;
|
||||
io.lockx.in.lock_cnt = 0;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = lock;
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
torture_comment(tctx, "testing cancel 2/2 lock request\n");
|
||||
|
||||
/* Lock second range so it contends */
|
||||
io.lockx.in.timeout = 0;
|
||||
io.lockx.in.ulock_cnt = 0;
|
||||
io.lockx.in.lock_cnt = 1;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = &lock[1];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
/* Send request with two ranges */
|
||||
io.lockx.in.timeout = -1;
|
||||
io.lockx.in.ulock_cnt = 0;
|
||||
io.lockx.in.lock_cnt = 2;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = lock;
|
||||
req = smb_raw_lock_send(cli->tree, &io);
|
||||
torture_assert(tctx,(req != NULL), talloc_asprintf(tctx,
|
||||
"Failed to setup pending lock (%s)\n", __location__));
|
||||
|
||||
/* Try to cancel the second lock range */
|
||||
io.lockx.in.timeout = 0;
|
||||
io.lockx.in.lock_cnt = 1;
|
||||
io.lockx.in.mode = LOCKING_ANDX_CANCEL_LOCK | LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = &lock[1];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
/* Locking request should've failed and first range should be
|
||||
* unlocked */
|
||||
status = smbcli_request_simple_recv(req);
|
||||
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
|
||||
|
||||
io.lockx.in.timeout = 0;
|
||||
io.lockx.in.ulock_cnt = 0;
|
||||
io.lockx.in.lock_cnt = 1;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = &lock[0];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
/* Cleanup both locks */
|
||||
io.lockx.in.ulock_cnt = 2;
|
||||
io.lockx.in.lock_cnt = 0;
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.locks = lock;
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
torture_comment(tctx, "testing cancel by unlock\n");
|
||||
io.lockx.in.ulock_cnt = 0;
|
||||
io.lockx.in.lock_cnt = 1;
|
||||
@ -654,7 +748,7 @@ static bool test_async(struct torture_context *tctx,
|
||||
io.lockx.in.timeout = 0;
|
||||
io.lockx.in.locks = &lock[0];
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
|
||||
CHECK_STATUS(status, NT_STATUS_OK);
|
||||
|
||||
io.lockx.in.timeout = 5000;
|
||||
req = smb_raw_lock_send(cli->tree, &io);
|
||||
@ -680,7 +774,7 @@ static bool test_async(struct torture_context *tctx,
|
||||
io.lockx.in.mode = LOCKING_ANDX_LARGE_FILES;
|
||||
io.lockx.in.timeout = 0;
|
||||
status = smb_raw_lock(cli->tree, &io);
|
||||
CHECK_STATUS(status, NT_STATUS_FILE_LOCK_CONFLICT);
|
||||
CHECK_STATUS(status, NT_STATUS_LOCK_NOT_GRANTED);
|
||||
|
||||
t = time(NULL);
|
||||
io.lockx.in.timeout = 10000;
|
||||
|
@ -5,7 +5,7 @@
|
||||
Copyright (C) Tim Potter 2003
|
||||
Copyright (C) Stefan Metzmacher 2005
|
||||
Copyright (C) Jelmer Vernooij 2007
|
||||
Copyright (C) Guenther Deschner 2009
|
||||
Copyright (C) Guenther Deschner 2009-2010
|
||||
|
||||
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
|
||||
@ -865,45 +865,67 @@ static bool test_GetPrinterDriver2(struct torture_context *tctx,
|
||||
struct policy_handle *handle,
|
||||
const char *driver_name);
|
||||
|
||||
static bool test_GetPrinter(struct torture_context *tctx,
|
||||
static bool test_GetPrinter_level(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle)
|
||||
struct policy_handle *handle,
|
||||
uint32_t level,
|
||||
union spoolss_PrinterInfo *info)
|
||||
{
|
||||
NTSTATUS status;
|
||||
struct spoolss_GetPrinter r;
|
||||
uint16_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
int i;
|
||||
uint32_t needed;
|
||||
|
||||
for (i=0;i<ARRAY_SIZE(levels);i++) {
|
||||
r.in.handle = handle;
|
||||
r.in.level = levels[i];
|
||||
r.in.level = level;
|
||||
r.in.buffer = NULL;
|
||||
r.in.offered = 0;
|
||||
r.out.needed = &needed;
|
||||
|
||||
torture_comment(tctx, "Testing GetPrinter level %u\n", r.in.level);
|
||||
|
||||
status = dcerpc_spoolss_GetPrinter(p, tctx, &r);
|
||||
torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
|
||||
torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinter(p, tctx, &r),
|
||||
"GetPrinter failed");
|
||||
|
||||
if (W_ERROR_EQUAL(r.out.result, WERR_INSUFFICIENT_BUFFER)) {
|
||||
DATA_BLOB blob = data_blob_talloc(tctx, NULL, needed);
|
||||
data_blob_clear(&blob);
|
||||
r.in.buffer = &blob;
|
||||
r.in.offered = needed;
|
||||
status = dcerpc_spoolss_GetPrinter(p, tctx, &r);
|
||||
}
|
||||
|
||||
torture_assert_ntstatus_ok(tctx, status, "GetPrinter failed");
|
||||
torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_GetPrinter(p, tctx, &r),
|
||||
"GetPrinter failed");
|
||||
}
|
||||
|
||||
torture_assert_werr_ok(tctx, r.out.result, "GetPrinter failed");
|
||||
|
||||
CHECK_NEEDED_SIZE_LEVEL(spoolss_PrinterInfo, r.out.info, r.in.level, lp_iconv_convenience(tctx->lp_ctx), needed, 4);
|
||||
|
||||
if ((r.in.level == 2) && r.out.info->info2.drivername && strlen(r.out.info->info2.drivername)) {
|
||||
if (info && r.out.info) {
|
||||
*info = *r.out.info;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static bool test_GetPrinter(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle)
|
||||
{
|
||||
uint32_t levels[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
|
||||
int i;
|
||||
|
||||
for (i=0;i<ARRAY_SIZE(levels);i++) {
|
||||
|
||||
union spoolss_PrinterInfo info;
|
||||
|
||||
ZERO_STRUCT(info);
|
||||
|
||||
torture_assert(tctx, test_GetPrinter_level(tctx, p, handle, levels[i], &info),
|
||||
"failed to call GetPrinter");
|
||||
|
||||
if ((levels[i] == 2) && info.info2.drivername && strlen(info.info2.drivername)) {
|
||||
torture_assert(tctx,
|
||||
test_GetPrinterDriver2(tctx, p, handle, r.out.info->info2.drivername),
|
||||
test_GetPrinterDriver2(tctx, p, handle, info.info2.drivername),
|
||||
"failed to call test_GetPrinterDriver2");
|
||||
}
|
||||
}
|
||||
@ -911,6 +933,32 @@ static bool test_GetPrinter(struct torture_context *tctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_SetPrinter(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle,
|
||||
struct spoolss_SetPrinterInfoCtr *info_ctr,
|
||||
struct spoolss_DevmodeContainer *devmode_ctr,
|
||||
struct sec_desc_buf *secdesc_ctr,
|
||||
enum spoolss_PrinterControl command)
|
||||
{
|
||||
struct spoolss_SetPrinter r;
|
||||
|
||||
r.in.handle = handle;
|
||||
r.in.info_ctr = info_ctr;
|
||||
r.in.devmode_ctr = devmode_ctr;
|
||||
r.in.secdesc_ctr = secdesc_ctr;
|
||||
r.in.command = command;
|
||||
|
||||
torture_comment(tctx, "Testing SetPrinter Level %d\n", r.in.info_ctr->level);
|
||||
|
||||
torture_assert_ntstatus_ok(tctx, dcerpc_spoolss_SetPrinter(p, tctx, &r),
|
||||
"failed to call SetPrinter");
|
||||
torture_assert_werr_ok(tctx, r.out.result,
|
||||
"failed to call SetPrinter");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_SetPrinter_errors(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle)
|
||||
@ -2618,6 +2666,181 @@ static bool test_SetPrinterDataEx(struct torture_context *tctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_GetChangeID_PrinterData(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle,
|
||||
uint32_t *change_id)
|
||||
{
|
||||
enum winreg_Type type;
|
||||
union spoolss_PrinterData data;
|
||||
|
||||
torture_assert(tctx,
|
||||
test_GetPrinterData(tctx, p, handle, "ChangeID", &type, &data),
|
||||
"failed to call GetPrinterData");
|
||||
|
||||
torture_assert(tctx, type == REG_DWORD, "unexpected type");
|
||||
|
||||
*change_id = data.value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_GetChangeID_PrinterDataEx(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle,
|
||||
uint32_t *change_id)
|
||||
{
|
||||
enum winreg_Type type;
|
||||
union spoolss_PrinterData data;
|
||||
|
||||
torture_assert(tctx,
|
||||
test_GetPrinterDataEx(tctx, p, handle, "PrinterDriverData", "ChangeID", &type, &data),
|
||||
"failed to call GetPrinterData");
|
||||
|
||||
torture_assert(tctx, type == REG_DWORD, "unexpected type");
|
||||
|
||||
*change_id = data.value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_GetChangeID_PrinterInfo(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle,
|
||||
uint32_t *change_id)
|
||||
{
|
||||
union spoolss_PrinterInfo info;
|
||||
|
||||
torture_assert(tctx, test_GetPrinter_level(tctx, p, handle, 0, &info),
|
||||
"failed to query Printer level 0");
|
||||
|
||||
*change_id = info.info0.change_id;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_ChangeID(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
struct policy_handle *handle)
|
||||
{
|
||||
uint32_t change_id, change_id_ex, change_id_info;
|
||||
uint32_t change_id2, change_id_ex2, change_id_info2;
|
||||
union spoolss_PrinterInfo info;
|
||||
const char *comment;
|
||||
|
||||
|
||||
torture_comment(tctx, "Testing ChangeID: id change test #1\n");
|
||||
|
||||
torture_assert(tctx, test_GetChangeID_PrinterData(tctx, p, handle, &change_id),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, p, handle, &change_id_info),
|
||||
"failed to query for ChangeID");
|
||||
|
||||
torture_assert_int_equal(tctx, change_id, change_id_ex,
|
||||
"change_ids should all be equal");
|
||||
torture_assert_int_equal(tctx, change_id_ex, change_id_info,
|
||||
"change_ids should all be equal");
|
||||
|
||||
|
||||
torture_comment(tctx, "Testing ChangeID: id change test #2\n");
|
||||
|
||||
torture_assert(tctx, test_GetChangeID_PrinterData(tctx, p, handle, &change_id),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetPrinter_level(tctx, p, handle, 2, &info),
|
||||
"failed to query Printer level 2");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, p, handle, &change_id_info),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert_int_equal(tctx, change_id, change_id_ex,
|
||||
"change_id should not have changed");
|
||||
torture_assert_int_equal(tctx, change_id_ex, change_id_info,
|
||||
"change_id should not have changed");
|
||||
|
||||
|
||||
torture_comment(tctx, "Testing ChangeID: id change test #3\n");
|
||||
|
||||
torture_assert(tctx, test_GetChangeID_PrinterData(tctx, p, handle, &change_id),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, p, handle, &change_id_info),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetPrinter_level(tctx, p, handle, 2, &info),
|
||||
"failed to query Printer level 2");
|
||||
comment = talloc_strdup(tctx, info.info2.comment);
|
||||
|
||||
{
|
||||
struct spoolss_SetPrinterInfoCtr info_ctr;
|
||||
struct spoolss_DevmodeContainer devmode_ctr;
|
||||
struct sec_desc_buf secdesc_ctr;
|
||||
struct spoolss_SetPrinterInfo2 info2;
|
||||
|
||||
ZERO_STRUCT(info_ctr);
|
||||
ZERO_STRUCT(devmode_ctr);
|
||||
ZERO_STRUCT(secdesc_ctr);
|
||||
|
||||
info2.servername = info.info2.servername;
|
||||
info2.printername = info.info2.printername;
|
||||
info2.sharename = info.info2.sharename;
|
||||
info2.portname = info.info2.portname;
|
||||
info2.drivername = info.info2.drivername;
|
||||
info2.comment = "torture_comment";
|
||||
info2.location = info.info2.location;
|
||||
info2.devmode_ptr = 0;
|
||||
info2.sepfile = info.info2.sepfile;
|
||||
info2.printprocessor = info.info2.printprocessor;
|
||||
info2.datatype = info.info2.datatype;
|
||||
info2.parameters = info.info2.parameters;
|
||||
info2.secdesc_ptr = 0;
|
||||
info2.attributes = info.info2.attributes;
|
||||
info2.priority = info.info2.priority;
|
||||
info2.defaultpriority = info.info2.defaultpriority;
|
||||
info2.starttime = info.info2.starttime;
|
||||
info2.untiltime = info.info2.untiltime;
|
||||
info2.status = info.info2.status;
|
||||
info2.cjobs = info.info2.cjobs;
|
||||
info2.averageppm = info.info2.averageppm;
|
||||
|
||||
info_ctr.level = 2;
|
||||
info_ctr.info.info2 = &info2;
|
||||
|
||||
torture_assert(tctx, test_SetPrinter(tctx, p, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
|
||||
"failed to call SetPrinter");
|
||||
|
||||
info2.comment = comment;
|
||||
|
||||
torture_assert(tctx, test_SetPrinter(tctx, p, handle, &info_ctr, &devmode_ctr, &secdesc_ctr, 0),
|
||||
"failed to call SetPrinter");
|
||||
|
||||
}
|
||||
|
||||
torture_assert(tctx, test_GetChangeID_PrinterData(tctx, p, handle, &change_id2),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterDataEx(tctx, p, handle, &change_id_ex2),
|
||||
"failed to query for ChangeID");
|
||||
torture_assert(tctx, test_GetChangeID_PrinterInfo(tctx, p, handle, &change_id_info2),
|
||||
"failed to query for ChangeID");
|
||||
|
||||
torture_assert_int_equal(tctx, change_id2, change_id_ex2,
|
||||
"change_ids should all be equal");
|
||||
torture_assert_int_equal(tctx, change_id_ex2, change_id_info2,
|
||||
"change_ids should all be equal");
|
||||
|
||||
torture_assert(tctx, (change_id < change_id2),
|
||||
talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
|
||||
change_id2, change_id));
|
||||
torture_assert(tctx, (change_id_ex < change_id_ex2),
|
||||
talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
|
||||
change_id_ex2, change_id_ex));
|
||||
torture_assert(tctx, (change_id_info < change_id_info2),
|
||||
talloc_asprintf(tctx, "change_id %d needs to be larger than change_id %d",
|
||||
change_id_info2, change_id_info));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool test_SecondaryClosePrinter(struct torture_context *tctx,
|
||||
struct dcerpc_pipe *p,
|
||||
@ -2848,6 +3071,10 @@ static bool test_OpenPrinterEx(struct torture_context *tctx,
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (!test_ChangeID(tctx, p, &handle)) {
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (!torture_setting_bool(tctx, "samba3", false)) {
|
||||
if (!test_SecondaryClosePrinter(tctx, p, &handle)) {
|
||||
ret = false;
|
||||
|
@ -52,16 +52,16 @@ testit "export keytab from domain (2nd time)" $VALGRIND $net export keytab $PREF
|
||||
KRB5CCNAME="$PREFIX/tmpuserccache"
|
||||
export KRB5CCNAME
|
||||
|
||||
testit "kinit with keytab as user" $samba4kinit --keytab=$PREFIX/tmpkeytab --request-pac nettestuser@$REALM || failed=`expr $failed + 1`
|
||||
testit "kinit with keytab as user" $VALGRIND $samba4kinit --keytab=$PREFIX/tmpkeytab --request-pac nettestuser@$REALM || failed=`expr $failed + 1`
|
||||
|
||||
test_smbclient "Test login with user kerberos ccache" 'ls' -k yes || failed=`expr $failed + 1`
|
||||
|
||||
KRB5CCNAME="$PREFIX/tmpadminccache"
|
||||
export KRB5CCNAME
|
||||
|
||||
testit "kinit with keytab as $USERNAME" $samba4kinit --keytab=$PREFIX/tmpkeytab --request-pac $USERNAME@$REALM || failed=`expr $failed + 1`
|
||||
testit "kinit with keytab as $USERNAME" $VALGRIND $samba4kinit --keytab=$PREFIX/tmpkeytab --request-pac $USERNAME@$REALM || failed=`expr $failed + 1`
|
||||
|
||||
testit "del user" $VALGRIND $net user delete nettestuser -k yes $@ || failed=`expr $failed + 1`
|
||||
|
||||
rm -f tmpadminccache tmpuserccache tmpkeytab
|
||||
rm -f $PREFIX/tmpadminccache $PREFIX/tmpuserccache $PREFIX/tmpkeytab
|
||||
exit $failed
|
||||
|
Loading…
Reference in New Issue
Block a user