summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-10-26 14:57:11 +0000
committerGerald Carter <jerry@samba.org>2006-10-26 14:57:11 +0000
commit47dde11977c259e804ae67f1507d0e2f7e8263fc (patch)
tree68f478569486c25986b003fd62b5b0d40819435f /source
parent6cd6987fc504a8056295113c12f629ad5c4b2868 (diff)
downloadsamba-47dde11977c259e804ae67f1507d0e2f7e8263fc.tar.gz
samba-47dde11977c259e804ae67f1507d0e2f7e8263fc.tar.xz
samba-47dde11977c259e804ae67f1507d0e2f7e8263fc.zip
r19499: sync up changes for 3.0.23d
Diffstat (limited to 'source')
-rw-r--r--source/configure.in10
-rw-r--r--source/include/doserr.h2
-rw-r--r--source/include/rpc_netlogon.h2
-rw-r--r--source/lib/gencache.c24
-rw-r--r--source/lib/system_smbd.c15
-rw-r--r--source/lib/util.c7
-rw-r--r--source/lib/util_nscd.c42
-rw-r--r--source/libads/ldap_printer.c10
-rw-r--r--source/libsmb/cliconnect.c17
-rw-r--r--source/libsmb/clispnego.c19
-rw-r--r--source/libsmb/doserr.c2
-rw-r--r--source/libsmb/namequery.c2
-rw-r--r--source/nsswitch/pam_winbind.c20
-rw-r--r--source/nsswitch/pam_winbind.h1
-rw-r--r--source/nsswitch/wb_common.c22
-rw-r--r--source/nsswitch/winbindd_async.c10
-rw-r--r--source/nsswitch/winbindd_cache.c3
-rw-r--r--source/nsswitch/winbindd_cm.c7
-rw-r--r--source/nsswitch/winbindd_misc.c7
-rw-r--r--source/nsswitch/winbindd_rpc.c9
-rw-r--r--source/nsswitch/winbindd_user.c6
-rw-r--r--source/passdb/pdb_get_set.c24
-rw-r--r--source/passdb/pdb_interface.c16
-rw-r--r--source/passdb/pdb_ldap.c2
-rw-r--r--source/rpc_client/cli_netlogon.c14
-rw-r--r--source/rpc_parse/parse_net.c2
-rw-r--r--source/rpc_parse/parse_samr.c15
-rw-r--r--source/rpc_server/srv_samr_util.c108
-rw-r--r--source/rpcclient/cmd_netlogon.c14
-rw-r--r--source/rpcclient/cmd_samr.c6
-rw-r--r--source/smbd/quotas.c16
-rw-r--r--source/utils/net_ads.c11
-rw-r--r--source/utils/net_rpc_samsync.c64
-rw-r--r--source/utils/net_sam.c56
-rw-r--r--source/utils/pdbedit.c79
35 files changed, 445 insertions, 219 deletions
diff --git a/source/configure.in b/source/configure.in
index a2a733a61d2..879f6f2909b 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -242,7 +242,6 @@ dnl Unique-to-Samba variables we'll be playing with.
AC_SUBST(SHELL)
AC_SUBST(LDSHFLAGS)
AC_SUBST(SONAMEFLAG)
-AC_SUBST(NSSSONAMEVERSIONSUFFIX)
AC_SUBST(SHLD)
AC_SUBST(HOST_OS)
AC_SUBST(PICFLAGS)
@@ -1639,7 +1638,6 @@ BLDSHARED="false"
HOST_OS="$host_os"
LDSHFLAGS="-shared"
SONAMEFLAG="#"
-NSSSONAMEVERSIONSUFFIX=""
SHLD="\${CC} \${CFLAGS}"
PICFLAGS=""
PICSUFFIX="po"
@@ -1664,7 +1662,6 @@ if test "$enable_shared" = "yes"; then
DYNEXP="-Wl,--export-dynamic"
PICFLAGS="-fPIC"
SONAMEFLAG="-Wl,-soname="
- NSSSONAMEVERSIONSUFFIX=".2"
AC_DEFINE(STAT_ST_BLOCKSIZE,512)
;;
*solaris*) AC_DEFINE(SUNOS5,1,[Whether the host os is solaris])
@@ -1674,7 +1671,6 @@ if test "$enable_shared" = "yes"; then
if test "${GCC}" = "yes"; then
PICFLAGS="-fPIC"
SONAMEFLAG="-Wl,-soname="
- NSSSONAMEVERSIONSUFFIX=".1"
if test "${ac_cv_prog_gnu_ld}" = "yes"; then
DYNEXP="-Wl,-E"
fi
@@ -4883,6 +4879,7 @@ AC_ARG_WITH(aio-support,
AC_MSG_RESULT(yes)
case "$host_os" in
*)
+ AIO_LIBS=$LIBS
AC_CHECK_LIB(rt,aio_read,[AIO_LIBS="$LIBS -lrt"])
AC_CHECK_LIB(aio,aio_read,[AIO_LIBS="$LIBS -laio"])
AC_CACHE_CHECK([for asynchronous io support],samba_cv_HAVE_AIO,[
@@ -5283,14 +5280,17 @@ HAVE_WINBIND=yes
WINBIND_NSS="nsswitch/libnss_winbind.$SHLIBEXT"
WINBIND_WINS_NSS="nsswitch/libnss_wins.$SHLIBEXT"
WINBIND_NSS_LDSHFLAGS=$LDSHFLAGS
+NSSSONAMEVERSIONSUFFIX=""
case "$host_os" in
*linux*)
+ NSSSONAMEVERSIONSUFFIX=".2"
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_linux.o"
;;
*freebsd[[5-9]]*)
# FreeBSD winbind client is implemented as a wrapper around
# the Linux version.
+ NSSSONAMEVERSIONSUFFIX=".1"
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_freebsd.o \
nsswitch/winbind_nss_linux.o"
WINBIND_NSS="nsswitch/nss_winbind.$SHLIBEXT"
@@ -5305,6 +5305,7 @@ case "$host_os" in
*solaris*)
# Solaris winbind client is implemented as a wrapper around
# the Linux version.
+ NSSSONAMEVERSIONSUFFIX=".1"
WINBIND_NSS_EXTRA_OBJS="nsswitch/winbind_nss_solaris.o \
nsswitch/winbind_nss_linux.o"
WINBIND_NSS_EXTRA_LIBS="-lsocket"
@@ -5331,6 +5332,7 @@ AC_SUBST(WINBIND_WINS_NSS)
AC_SUBST(WINBIND_NSS_LDSHFLAGS)
AC_SUBST(WINBIND_NSS_EXTRA_OBJS)
AC_SUBST(WINBIND_NSS_EXTRA_LIBS)
+AC_SUBST(NSSSONAMEVERSIONSUFFIX)
# Check the setting of --with-winbind
diff --git a/source/include/doserr.h b/source/include/doserr.h
index bc381e33515..4e3a85ff73f 100644
--- a/source/include/doserr.h
+++ b/source/include/doserr.h
@@ -201,6 +201,8 @@
#define WERR_SERVICE_DISABLED W_ERROR(1058)
#define WERR_SERVICE_NEVER_STARTED W_ERROR(1077)
#define WERR_MACHINE_LOCKED W_ERROR(1271)
+#define WERR_NO_LOGON_SERVERS W_ERROR(1311)
+#define WERR_NO_SUCH_DOMAIN W_ERROR(1355)
#define WERR_INVALID_SECURITY_DESCRIPTOR W_ERROR(1338)
#define WERR_TIME_SKEW W_ERROR(1398)
#define WERR_EVENTLOG_FILE_CORRUPT W_ERROR(1500)
diff --git a/source/include/rpc_netlogon.h b/source/include/rpc_netlogon.h
index 9df7701de41..01b6b99cbf6 100644
--- a/source/include/rpc_netlogon.h
+++ b/source/include/rpc_netlogon.h
@@ -431,7 +431,7 @@ typedef struct net_q_getdcname {
typedef struct net_r_getdcname {
uint32 ptr_dcname;
UNISTR2 uni_dcname;
- NTSTATUS status;
+ WERROR status;
} NET_R_GETDCNAME;
/* NET_Q_TRUST_DOM_LIST - LSA Query Trusted Domains */
diff --git a/source/lib/gencache.c b/source/lib/gencache.c
index 561a019429a..75a8f2f1e16 100644
--- a/source/lib/gencache.c
+++ b/source/lib/gencache.c
@@ -31,6 +31,7 @@
#define READ_CACHE_DATA_FMT_TEMPLATE "%%12u/%%%us"
static TDB_CONTEXT *cache;
+static BOOL cache_readonly;
/**
* @file gencache.c
@@ -66,6 +67,14 @@ BOOL gencache_init(void)
cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT,
O_RDWR|O_CREAT, 0644);
+ if (!cache && (errno == EACCES)) {
+ cache = tdb_open_log(cache_fname, 0, TDB_DEFAULT, O_RDONLY, 0644);
+ if (cache) {
+ cache_readonly = True;
+ DEBUG(5, ("gencache_init: Opening cache file %s read-only.\n", cache_fname));
+ }
+ }
+
SAFE_FREE(cache_fname);
if (!cache) {
DEBUG(5, ("Attempt to open gencache.tdb has failed.\n"));
@@ -90,6 +99,7 @@ BOOL gencache_shutdown(void)
DEBUG(5, ("Closing cache file\n"));
ret = tdb_close(cache);
cache = NULL;
+ cache_readonly = False;
return ret != -1;
}
@@ -117,6 +127,10 @@ BOOL gencache_set(const char *keystr, const char *value, time_t timeout)
if (!gencache_init()) return False;
+ if (cache_readonly) {
+ return False;
+ }
+
asprintf(&valstr, CACHE_DATA_FMT, (int)timeout, value);
if (!valstr)
return False;
@@ -162,6 +176,10 @@ BOOL gencache_set_only(const char *keystr, const char *valstr, time_t timeout)
if (!gencache_init()) return False;
+ if (cache_readonly) {
+ return False;
+ }
+
/*
* Check whether entry exists in the cache
* Don't verify gencache_get exit code, since the entry may be expired
@@ -213,6 +231,10 @@ BOOL gencache_del(const char *keystr)
if (!gencache_init()) return False;
+ if (cache_readonly) {
+ return False;
+ }
+
keybuf.dptr = SMB_STRDUP(keystr);
keybuf.dsize = strlen(keystr)+1;
DEBUG(10, ("Deleting cache entry (key = %s)\n", keystr));
@@ -431,5 +453,3 @@ void gencache_unlock_entry( const char *key )
tdb_unlock_bystring(cache, key);
return;
}
-
-
diff --git a/source/lib/system_smbd.c b/source/lib/system_smbd.c
index afa64489cfd..fc506c901db 100644
--- a/source/lib/system_smbd.c
+++ b/source/lib/system_smbd.c
@@ -120,19 +120,15 @@ static int getgrouplist_internals(const char *user, gid_t gid, gid_t *groups,
static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
int retval;
- char *winbindd_env;
+ BOOL winbind_env;
DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
- /* Save the winbindd state and not just blindly turn it back on */
-
- winbindd_env = getenv(WINBINDD_DONT_ENV);
-
/* This is only ever called for Unix users, remote memberships are
* always determined by the info3 coming back from auth3 or the
* PAC. */
-
- winbind_off() ;
+ winbind_env = winbind_env_set();
+ winbind_off();
#ifdef HAVE_GETGROUPLIST
retval = getgrouplist(user, gid, groups, grpcnt);
@@ -142,9 +138,8 @@ static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grp
unbecome_root();
#endif
- /* allow winbindd lookups , but only if they were not already disabled */
-
- if ( !(winbindd_env && strequal(winbindd_env, "1")) ) {
+ /* allow winbindd lookups, but only if they were not already disabled */
+ if (!winbind_env) {
winbind_on();
}
diff --git a/source/lib/util.c b/source/lib/util.c
index 12be5bc6c04..9738326ce67 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -312,6 +312,13 @@ void add_gid_to_array_unique(TALLOC_CTX *mem_ctx, gid_t gid,
{
int i;
+ if ((*num_gids != 0) && (*gids == NULL)) {
+ /*
+ * A former call to this routine has failed to allocate memory
+ */
+ return;
+ }
+
for (i=0; i<*num_gids; i++) {
if ((*gids)[i] == gid)
return;
diff --git a/source/lib/util_nscd.c b/source/lib/util_nscd.c
new file mode 100644
index 00000000000..f2106c1d063
--- /dev/null
+++ b/source/lib/util_nscd.c
@@ -0,0 +1,42 @@
+/*
+ Unix SMB/CIFS implementation.
+ Samba utility functions
+ Copyright (C) Guenther Deschner 2006
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+static void smb_nscd_flush_cache(const char *service)
+{
+#ifdef HAVE_NSCD_FLUSH_CACHE
+ if (!nscd_flush_cache(service)) {
+ DEBUG(10,("failed to flush nscd cache for '%s' service: %s. "
+ "Is nscd running?\n",
+ service, strerror(errno)));
+ }
+#endif
+}
+
+void smb_nscd_flush_user_cache(void)
+{
+ smb_nscd_flush_cache("passwd");
+}
+
+void smb_nscd_flush_group_cache(void)
+{
+ smb_nscd_flush_cache("group");
+}
diff --git a/source/libads/ldap_printer.c b/source/libads/ldap_printer.c
index 12bf6eec1df..2d2664979cd 100644
--- a/source/libads/ldap_printer.c
+++ b/source/libads/ldap_printer.c
@@ -40,8 +40,18 @@ ADS_STATUS ads_find_printer_on_server(ADS_STRUCT *ads, void **res,
servername));
return status;
}
+ if (ads_count_replies(ads, *res) != 1) {
+ return ADS_ERROR(LDAP_NO_SUCH_OBJECT);
+ }
srv_dn = ldap_get_dn(ads->ld, *res);
+ if (srv_dn == NULL) {
+ return ADS_ERROR(LDAP_NO_MEMORY);
+ }
srv_cn = ldap_explode_dn(srv_dn, 1);
+ if (srv_cn == NULL) {
+ ldap_memfree(srv_dn);
+ return ADS_ERROR(LDAP_INVALID_DN_SYNTAX);
+ }
ads_msgfree(ads, *res);
asprintf(&s, "(cn=%s-%s)", srv_cn[0], printer);
diff --git a/source/libsmb/cliconnect.c b/source/libsmb/cliconnect.c
index 7f5b5d7fa57..820680b1322 100644
--- a/source/libsmb/cliconnect.c
+++ b/source/libsmb/cliconnect.c
@@ -746,15 +746,26 @@ ADS_STATUS cli_session_setup_spnego(struct cli_state *cli, const char *user,
/* make sure the server understands kerberos */
for (i=0;OIDs[i];i++) {
DEBUG(3,("got OID=%s\n", OIDs[i]));
-#ifdef HAVE_KRB5
if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
strcmp(OIDs[i], OID_KERBEROS5) == 0) {
got_kerberos_mechanism = True;
}
-#endif
free(OIDs[i]);
}
- DEBUG(3,("got principal=%s\n", principal));
+
+ DEBUG(3,("got principal=%s\n", principal ? principal : "<null>"));
+
+ if (got_kerberos_mechanism && (principal == NULL)) {
+ /*
+ * It is WRONG to depend on the principal sent in the negprot
+ * reply, but right now we do it. So for safety (don't
+ * segfault later) disable Kerberos when no principal was
+ * sent. -- VL
+ */
+ DEBUG(1, ("Kerberos mech was offered, but no principal was "
+ "sent, disabling Kerberos\n"));
+ cli->use_kerberos = False;
+ }
fstrcpy(cli->user_name, user);
diff --git a/source/libsmb/clispnego.c b/source/libsmb/clispnego.c
index 3dad37d9e1b..a01c009b6e3 100644
--- a/source/libsmb/clispnego.c
+++ b/source/libsmb/clispnego.c
@@ -149,13 +149,16 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob,
asn1_end_tag(&data);
asn1_end_tag(&data);
- asn1_start_tag(&data, ASN1_CONTEXT(3));
- asn1_start_tag(&data, ASN1_SEQUENCE(0));
- asn1_start_tag(&data, ASN1_CONTEXT(0));
- asn1_read_GeneralString(&data,principal);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
- asn1_end_tag(&data);
+ *principal = NULL;
+ if (asn1_tag_remaining(&data) > 0) {
+ asn1_start_tag(&data, ASN1_CONTEXT(3));
+ asn1_start_tag(&data, ASN1_SEQUENCE(0));
+ asn1_start_tag(&data, ASN1_CONTEXT(0));
+ asn1_read_GeneralString(&data,principal);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ asn1_end_tag(&data);
+ }
asn1_end_tag(&data);
asn1_end_tag(&data);
@@ -165,7 +168,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob,
ret = !data.has_error;
if (data.has_error) {
int j;
- SAFE_FREE(principal);
+ SAFE_FREE(*principal);
for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) {
SAFE_FREE(OIDs[j]);
}
diff --git a/source/libsmb/doserr.c b/source/libsmb/doserr.c
index 253164963a4..8628db3abc9 100644
--- a/source/libsmb/doserr.c
+++ b/source/libsmb/doserr.c
@@ -67,6 +67,8 @@ werror_code_struct dos_errs[] =
{ "WERR_DFS_INTERNAL_ERROR", WERR_DFS_INTERNAL_ERROR },
{ "WERR_DFS_CANT_CREATE_JUNCT", WERR_DFS_CANT_CREATE_JUNCT },
{ "WERR_MACHINE_LOCKED", WERR_MACHINE_LOCKED },
+ { "WERR_NO_LOGON_SERVERS", WERR_NO_LOGON_SERVERS },
+ { "WERR_NO_SUCH_DOMAIN", WERR_NO_SUCH_DOMAIN },
{ "WERR_INVALID_SECURITY_DESCRIPTOR", WERR_INVALID_SECURITY_DESCRIPTOR },
{ "WERR_INVALID_OWNER", WERR_INVALID_OWNER },
{ "WERR_SERVER_UNAVAILABLE", WERR_SERVER_UNAVAILABLE },
diff --git a/source/libsmb/namequery.c b/source/libsmb/namequery.c
index eac63f53a2a..718cf28d22e 100644
--- a/source/libsmb/namequery.c
+++ b/source/libsmb/namequery.c
@@ -1034,7 +1034,7 @@ static BOOL resolve_ads(const char *name, int name_type,
if ( name_type != 0x1c )
return False;
- DEBUG(5,("resolve_hosts: Attempting to resolve DC's for %s using DNS\n",
+ DEBUG(5,("resolve_ads: Attempting to resolve DC's for %s using DNS\n",
name));
if ( (ctx = talloc_init("resolve_ads")) == NULL ) {
diff --git a/source/nsswitch/pam_winbind.c b/source/nsswitch/pam_winbind.c
index a81561fc9ab..fe0236b4987 100644
--- a/source/nsswitch/pam_winbind.c
+++ b/source/nsswitch/pam_winbind.c
@@ -508,6 +508,18 @@ static int winbind_auth_request(pam_handle_t * pamh,
}
}
+ /* save the profile path for other PAM modules */
+ if (response.data.auth.info3.profile_path[0] != '\0') {
+
+ int ret2 = pam_set_data(pamh, PAM_WINBIND_PROFILEPATH,
+ (void *) strdup(response.data.auth.info3.profile_path),
+ _pam_winbind_cleanup_func);
+ if (ret2) {
+ _pam_log_debug(ctrl, LOG_DEBUG, "Could not set data: %s",
+ pam_strerror(pamh, ret2));
+ }
+ }
+
return ret;
}
@@ -887,7 +899,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags,
const char *member = NULL;
const char *cctype = NULL;
int retval = PAM_AUTH_ERR;
- dictionary *d;
+ dictionary *d = NULL;
/* parse arguments */
int ctrl = _pam_parse(argc, argv, &d);
@@ -1068,7 +1080,7 @@ PAM_EXTERN
int pam_sm_close_session(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
- dictionary *d;
+ dictionary *d = NULL;
int retval = PAM_SUCCESS;
/* parse arguments */
@@ -1162,7 +1174,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
char *Announce;
int retry = 0;
- dictionary *d;
+ dictionary *d = NULL;
ctrl = _pam_parse(argc, argv, &d);
if (ctrl == -1) {
@@ -1251,7 +1263,7 @@ int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
goto out;
}
- pam_set_data(pamh, PAM_WINBIND_PWD_LAST_SET, (void *)pwdlastset_prelim, _pam_winbind_cleanup_func);
+ pam_set_data(pamh, PAM_WINBIND_PWD_LAST_SET, (void *)pwdlastset_prelim, NULL);
retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
pass_old = NULL;
diff --git a/source/nsswitch/pam_winbind.h b/source/nsswitch/pam_winbind.h
index 2b7080182be..bfa9ebf855b 100644
--- a/source/nsswitch/pam_winbind.h
+++ b/source/nsswitch/pam_winbind.h
@@ -109,6 +109,7 @@ do { \
#define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD"
#define PAM_WINBIND_HOMEDIR "PAM_WINBIND_HOMEDIR"
#define PAM_WINBIND_LOGONSCRIPT "PAM_WINBIND_LOGONSCRIPT"
+#define PAM_WINBIND_PROFILEPATH "PAM_WINBIND_PROFILEPATH"
#define PAM_WINBIND_PWD_LAST_SET "PAM_WINBIND_PWD_LAST_SET"
#define SECONDS_PER_DAY 86400
diff --git a/source/nsswitch/wb_common.c b/source/nsswitch/wb_common.c
index 91ebdbd5844..a6b6bd60997 100644
--- a/source/nsswitch/wb_common.c
+++ b/source/nsswitch/wb_common.c
@@ -518,6 +518,18 @@ int read_reply(struct winbindd_response *response)
return result1 + result2;
}
+BOOL winbind_env_set( void )
+{
+ char *env;
+
+ if ((env=getenv(WINBINDD_DONT_ENV)) != NULL) {
+ if(strcmp(env, "1") == 0) {
+ return True;
+ }
+ }
+ return False;
+}
+
/*
* send simple types of requests
*/
@@ -525,15 +537,11 @@ int read_reply(struct winbindd_response *response)
NSS_STATUS winbindd_send_request(int req_type, struct winbindd_request *request)
{
struct winbindd_request lrequest;
- char *env;
- int value;
-
+
/* Check for our tricky environment variable */
- if ( (env = getenv(WINBINDD_DONT_ENV)) != NULL ) {
- value = atoi(env);
- if ( value == 1 )
- return NSS_STATUS_NOTFOUND;
+ if (winbind_env_set()) {
+ return NSS_STATUS_NOTFOUND;
}
if (!request) {
diff --git a/source/nsswitch/winbindd_async.c b/source/nsswitch/winbindd_async.c
index cde5be8e4c9..1656c03261c 100644
--- a/source/nsswitch/winbindd_async.c
+++ b/source/nsswitch/winbindd_async.c
@@ -67,7 +67,7 @@ static void do_async(TALLOC_CTX *mem_ctx, struct winbindd_child *child,
{
struct do_async_state *state;
- state = TALLOC_P(mem_ctx, struct do_async_state);
+ state = TALLOC_ZERO_P(mem_ctx, struct do_async_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
cont(mem_ctx, False, NULL, c, private_data);
@@ -94,7 +94,7 @@ void do_async_domain(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
{
struct do_async_state *state;
- state = TALLOC_P(mem_ctx, struct do_async_state);
+ state = TALLOC_ZERO_P(mem_ctx, struct do_async_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
cont(mem_ctx, False, NULL, c, private_data);
@@ -981,7 +981,7 @@ void winbindd_gettoken_async(TALLOC_CTX *mem_ctx, const DOM_SID *user_sid,
struct winbindd_request request;
struct gettoken_state *state;
- state = TALLOC_P(mem_ctx, struct gettoken_state);
+ state = TALLOC_ZERO_P(mem_ctx, struct gettoken_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
cont(private_data, False, NULL, 0);
@@ -1147,7 +1147,7 @@ void winbindd_sid2uid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
return;
}
- state = TALLOC_P(mem_ctx, struct sid2uid_state);
+ state = TALLOC_ZERO_P(mem_ctx, struct sid2uid_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
cont(private_data, False, 0);
@@ -1309,7 +1309,7 @@ void winbindd_sid2gid_async(TALLOC_CTX *mem_ctx, const DOM_SID *sid,
return;
}
- state = TALLOC_P(mem_ctx, struct sid2gid_state);
+ state = TALLOC_ZERO_P(mem_ctx, struct sid2gid_state);
if (state == NULL) {
DEBUG(0, ("talloc failed\n"));
cont(private_data, False, 0);
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index ce7a6655985..cdb86f9f61b 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -1291,6 +1291,8 @@ do_query:
status = domain->backend->name_to_sid(domain, mem_ctx, domain_name, name, sid, type);
/* and save it */
+ refresh_sequence_number(domain, False);
+
if (domain->online && !is_null_sid(sid)) {
wcache_save_name_to_sid(domain, status, domain_name, name, sid, *type);
}
@@ -2144,6 +2146,7 @@ void cache_name2sid(struct winbindd_domain *domain,
const char *domain_name, const char *name,
enum SID_NAME_USE type, const DOM_SID *sid)
{
+ refresh_sequence_number(domain, False);
wcache_save_name_to_sid(domain, NT_STATUS_OK, domain_name, name,
sid, type);
}
diff --git a/source/nsswitch/winbindd_cm.c b/source/nsswitch/winbindd_cm.c
index c1276bd9612..98e799851fc 100644
--- a/source/nsswitch/winbindd_cm.c
+++ b/source/nsswitch/winbindd_cm.c
@@ -104,6 +104,7 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
struct winbindd_domain *our_domain = NULL;
struct rpc_pipe_client *netlogon_pipe = NULL;
NTSTATUS result;
+ WERROR werr;
TALLOC_CTX *mem_ctx;
fstring tmp;
@@ -131,14 +132,14 @@ static BOOL get_dc_name_via_netlogon(const struct winbindd_domain *domain,
return False;
}
- result = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
+ werr = rpccli_netlogon_getdcname(netlogon_pipe, mem_ctx, our_domain->dcname,
domain->name, tmp);
talloc_destroy(mem_ctx);
- if (!NT_STATUS_IS_OK(result)) {
+ if (!W_ERROR_IS_OK(werr)) {
DEBUG(10, ("rpccli_netlogon_getdcname failed: %s\n",
- nt_errstr(result)));
+ dos_errstr(werr)));
return False;
}
diff --git a/source/nsswitch/winbindd_misc.c b/source/nsswitch/winbindd_misc.c
index 6c6dc5b7651..731d2bb474a 100644
--- a/source/nsswitch/winbindd_misc.c
+++ b/source/nsswitch/winbindd_misc.c
@@ -189,6 +189,7 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
char *p;
struct rpc_pipe_client *netlogon_pipe;
NTSTATUS result;
+ WERROR werr;
state->request.domain_name
[sizeof(state->request.domain_name)-1] = '\0';
@@ -203,12 +204,12 @@ enum winbindd_result winbindd_dual_getdcname(struct winbindd_domain *domain,
return WINBINDD_ERROR;
}
- result = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, domain->dcname,
+ werr = rpccli_netlogon_getdcname(netlogon_pipe, state->mem_ctx, domain->dcname,
state->request.domain_name,
dcname_slash);
- if (!NT_STATUS_IS_OK(result)) {
- DEBUG(5, ("Error requesting DCname: %s\n", nt_errstr(result)));
+ if (!W_ERROR_IS_OK(werr)) {
+ DEBUG(5, ("Error requesting DCname: %s\n", dos_errstr(werr)));
return WINBINDD_ERROR;
}
diff --git a/source/nsswitch/winbindd_rpc.c b/source/nsswitch/winbindd_rpc.c
index 984c5cd8415..19ae5221ccd 100644
--- a/source/nsswitch/winbindd_rpc.c
+++ b/source/nsswitch/winbindd_rpc.c
@@ -563,6 +563,7 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
unsigned int j;
fstring sid_string;
struct rpc_pipe_client *cli;
+ unsigned int orig_timeout;
DEBUG(10,("rpc: lookup_groupmem %s sid=%s\n", domain->name,
sid_to_string(sid_string, group_sid)));
@@ -585,10 +586,18 @@ static NTSTATUS lookup_groupmem(struct winbindd_domain *domain,
/* Step #1: Get a list of user rids that are the members of the
group. */
+ /* This call can take a long time - allow the server to time out.
+ 35 seconds should do it. */
+
+ orig_timeout = cli_set_timeout(cli->cli, 35000);
+
result = rpccli_samr_query_groupmem(cli, mem_ctx,
&group_pol, num_names, &rid_mem,
name_types);
+ /* And restore our original timeout. */
+ cli_set_timeout(cli->cli, orig_timeout);
+
rpccli_samr_close(cli, mem_ctx, &group_pol);
if (!NT_STATUS_IS_OK(result))
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index 864bc5f0212..951fe319bdd 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -199,7 +199,7 @@ static void winbindd_getpwsid(struct winbindd_cli_state *state,
{
struct getpwsid_state *s;
- s = TALLOC_P(state->mem_ctx, struct getpwsid_state);
+ s = TALLOC_ZERO_P(state->mem_ctx, struct getpwsid_state);
if (s == NULL) {
DEBUG(0, ("talloc failed\n"));
goto error;
@@ -235,8 +235,8 @@ static void getpwsid_queryuser_recv(void *private_data, BOOL success,
talloc_get_type_abort(private_data, struct getpwsid_state);
if (!success) {
- DEBUG(5, ("Could not query user %s\\%s\n", s->domain->name,
- s->username));
+ DEBUG(5, ("Could not query domain %s SID %s\n", s->domain->name,
+ sid_string_static(&s->user_sid)));
request_error(s->state);
return;
}
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index 5bea6ce0c4a..f1b1a7673ca 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -72,32 +72,12 @@ time_t pdb_get_pass_last_set_time(const struct samu *sampass)
time_t pdb_get_pass_can_change_time(const struct samu *sampass)
{
- uint32 allow;
-
- if (sampass->pass_last_set_time == 0)
- return (time_t) 0;
-
- if (!pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &allow))
- allow = 0;
-
- return sampass->pass_last_set_time + allow;
+ return sampass->pass_can_change_time;
}
time_t pdb_get_pass_must_change_time(const struct samu *sampass)
{
- uint32 expire;
-
- if (sampass->pass_last_set_time == 0)
- return (time_t) 0;
-
- if (sampass->acct_ctrl & ACB_PWNOEXP)
- return get_time_t_max();
-
- if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
- || expire == (uint32)-1 || expire == 0)
- return get_time_t_max();
-
- return sampass->pass_last_set_time + expire;
+ return sampass->pass_must_change_time;
}
uint16 pdb_get_logon_divs(const struct samu *sampass)
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index 03530d34f78..8fefd989114 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -1327,27 +1327,25 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
struct group *grp;
char **gr;
struct passwd *pwd;
- char *winbindd_env;
+ BOOL winbind_env;
*pp_uids = NULL;
*p_num = 0;
/* We only look at our own sam, so don't care about imported stuff */
-
- winbindd_env = getenv(WINBINDD_DONT_ENV);
+ winbind_env = winbind_env_set();
winbind_off();
if ((grp = getgrgid(gid)) == NULL) {
/* allow winbindd lookups, but only if they weren't already disabled */
- if ( !(winbindd_env && strequal(winbindd_env, "1")) ) {
+ if (!winbind_env) {
winbind_on();
}
-
+
return False;
}
/* Primary group members */
-
setpwent();
while ((pwd = getpwent()) != NULL) {
if (pwd->pw_gid == gid) {
@@ -1358,7 +1356,6 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
endpwent();
/* Secondary group members */
-
for (gr = grp->gr_mem; (*gr != NULL) && ((*gr)[0] != '\0'); gr += 1) {
struct passwd *pw = getpwnam(*gr);
@@ -1368,11 +1365,10 @@ static BOOL get_memberuids(TALLOC_CTX *mem_ctx, gid_t gid, uid_t **pp_uids, size
}
/* allow winbindd lookups, but only if they weren't already disabled */
-
- if ( !(winbindd_env && strequal(winbindd_env, "1")) ) {
+ if (!winbind_env) {
winbind_on();
}
-
+
return True;
}
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index f6ca6e9eba9..54c250033dd 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -2405,7 +2405,7 @@ static NTSTATUS ldapsam_enum_group_members(struct pdb_methods *methods,
if (values) {
- filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBAACCOUNT);
+ filter = talloc_asprintf(mem_ctx, "(&(objectClass=%s)(|", LDAP_OBJ_SAMBASAMACCOUNT);
if (filter == NULL) {
ret = NT_STATUS_NO_MEMORY;
goto done;
diff --git a/source/rpc_client/cli_netlogon.c b/source/rpc_client/cli_netlogon.c
index 33f1d1d25ba..3a892cb7f4e 100644
--- a/source/rpc_client/cli_netlogon.c
+++ b/source/rpc_client/cli_netlogon.c
@@ -382,14 +382,14 @@ NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *me
/* GetDCName */
-NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx, const char *mydcname,
- const char *domainname, fstring newdcname)
+WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, const char *mydcname,
+ const char *domainname, fstring newdcname)
{
prs_struct qbuf, rbuf;
NET_Q_GETDCNAME q;
NET_R_GETDCNAME r;
- NTSTATUS result;
+ WERROR result;
fstring mydcname_slash;
ZERO_STRUCT(q);
@@ -402,16 +402,16 @@ NTSTATUS rpccli_netlogon_getdcname(struct rpc_pipe_client *cli,
/* Marshall data and send request */
- CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME,
+ CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME,
q, r,
qbuf, rbuf,
net_io_q_getdcname,
net_io_r_getdcname,
- NT_STATUS_UNSUCCESSFUL);
+ WERR_GENERAL_FAILURE);
result = r.status;
- if (NT_STATUS_IS_OK(result)) {
+ if (W_ERROR_IS_OK(result)) {
rpcstr_pull_unistr2_fstring(newdcname, &r.uni_dcname);
}
diff --git a/source/rpc_parse/parse_net.c b/source/rpc_parse/parse_net.c
index cecec314101..bc6b32e6ead 100644
--- a/source/rpc_parse/parse_net.c
+++ b/source/rpc_parse/parse_net.c
@@ -560,7 +560,7 @@ BOOL net_io_r_getdcname(const char *desc, NET_R_GETDCNAME *r_t, prs_struct *ps,
if (!prs_align(ps))
return False;
- if (!prs_ntstatus("status", ps, depth, &r_t->status))
+ if (!prs_werror("status", ps, depth, &r_t->status))
return False;
return True;
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 0503d308a55..0bde3da26c8 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -6208,7 +6208,6 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, struct samu *pw, DOM_SID *
pass_last_set_time, pass_can_change_time,
pass_must_change_time;
- time_t must_change_time;
const char* user_name = pdb_get_username(pw);
const char* full_name = pdb_get_fullname(pw);
const char* home_dir = pdb_get_homedir(pw);
@@ -6233,16 +6232,12 @@ NTSTATUS init_sam_user_info21A(SAM_USER_INFO_21 *usr, struct samu *pw, DOM_SID *
}
/* Create NTTIME structs */
- unix_to_nt_time (&logon_time, pdb_get_logon_time(pw));
- unix_to_nt_time (&logoff_time, pdb_get_logoff_time(pw));
+ unix_to_nt_time (&logon_time, pdb_get_logon_time(pw));
+ unix_to_nt_time (&logoff_time, pdb_get_logoff_time(pw));
unix_to_nt_time (&kickoff_time, pdb_get_kickoff_time(pw));
- unix_to_nt_time (&pass_last_set_time, pdb_get_pass_last_set_time(pw));
- unix_to_nt_time (&pass_can_change_time,pdb_get_pass_can_change_time(pw));
- must_change_time = pdb_get_pass_must_change_time(pw);
- if (must_change_time == get_time_t_max())
- unix_to_nt_time_abs(&pass_must_change_time, must_change_time);
- else
- unix_to_nt_time(&pass_must_change_time, must_change_time);
+ unix_to_nt_time (&pass_last_set_time, pdb_get_pass_last_set_time(pw));
+ unix_to_nt_time (&pass_can_change_time, pdb_get_pass_can_change_time(pw));
+ unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_time(pw));
/* structure assignment */
usr->logon_time = logon_time;
diff --git a/source/rpc_server/srv_samr_util.c b/source/rpc_server/srv_samr_util.c
index 4ce027ad70d..2b65eb210fd 100644
--- a/source/rpc_server/srv_samr_util.c
+++ b/source/rpc_server/srv_samr_util.c
@@ -99,6 +99,14 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from)
pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
}
+ if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
+ unix_time=nt_time_to_unix(&from->pass_can_change_time);
+ stored_time = pdb_get_pass_can_change_time(to);
+ DEBUG(10,("INFO_21 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
+ }
+
if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
unix_time=nt_time_to_unix(&from->pass_last_set_time);
stored_time = pdb_get_pass_last_set_time(to);
@@ -107,6 +115,14 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from)
pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
}
+ if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
+ unix_time=nt_time_to_unix(&from->pass_must_change_time);
+ stored_time=pdb_get_pass_must_change_time(to);
+ DEBUG(10,("INFO_21 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
+ }
+
if ((from->fields_present & ACCT_USERNAME) &&
(from->hdr_user_name.buffer)) {
old_string = pdb_get_username(to);
@@ -268,16 +284,26 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from)
}
}
- /* If the must change flag is set, the last set time goes to zero.
- the must change and can change fields also do, but they are
- calculated from policy, not set from the wire */
-
- if (from->fields_present & ACCT_EXPIRED_FLAG) {
- DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
- if (from->passmustchange == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
- pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
- } else {
- pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
+ DEBUG(10,("INFO_21 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
+ if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+ pdb_set_pass_must_change_time(to,0, PDB_CHANGED);
+ } else {
+ uint32 expire;
+ time_t new_time;
+ if (pdb_get_pass_must_change_time(to) == 0) {
+ if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
+ || expire == (uint32)-1) {
+ new_time = get_time_t_max();
+ } else {
+ time_t old_time = pdb_get_pass_last_set_time(to);
+ new_time = old_time + expire;
+ if ((new_time) < time(0)) {
+ new_time = time(0) + expire;
+ }
+ }
+ if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) {
+ DEBUG (0, ("pdb_set_pass_must_change_time failed!\n"));
+ }
}
}
@@ -322,6 +348,14 @@ void copy_id23_to_sam_passwd(struct samu *to, SAM_USER_INFO_23 *from)
pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
}
+ if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
+ unix_time=nt_time_to_unix(&from->pass_can_change_time);
+ stored_time = pdb_get_pass_can_change_time(to);
+ DEBUG(10,("INFO_23 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
+ }
+
if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
unix_time=nt_time_to_unix(&from->pass_last_set_time);
stored_time = pdb_get_pass_last_set_time(to);
@@ -330,6 +364,14 @@ void copy_id23_to_sam_passwd(struct samu *to, SAM_USER_INFO_23 *from)
pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
}
+ if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
+ unix_time=nt_time_to_unix(&from->pass_must_change_time);
+ stored_time=pdb_get_pass_must_change_time(to);
+ DEBUG(10,("INFO_23 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
+ }
+
/* Backend should check this for sanity */
if ((from->fields_present & ACCT_USERNAME) &&
(from->hdr_user_name.buffer)) {
@@ -482,16 +524,26 @@ void copy_id23_to_sam_passwd(struct samu *to, SAM_USER_INFO_23 *from)
}
}
- /* If the must change flag is set, the last set time goes to zero.
- the must change and can change fields also do, but they are
- calculated from policy, not set from the wire */
-
- if (from->fields_present & ACCT_EXPIRED_FLAG) {
- DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
- if (from->passmustchange == PASS_MUST_CHANGE_AT_NEXT_LOGON) {
- pdb_set_pass_last_set_time(to, 0, PDB_CHANGED);
- } else {
- pdb_set_pass_last_set_time(to, time(NULL),PDB_CHANGED);
+ DEBUG(10,("INFO_23 PASS_MUST_CHANGE_AT_NEXT_LOGON: %02X\n",from->passmustchange));
+ if (from->passmustchange==PASS_MUST_CHANGE_AT_NEXT_LOGON) {
+ pdb_set_pass_must_change_time(to,0, PDB_CHANGED);
+ } else {
+ uint32 expire;
+ time_t new_time;
+ if (pdb_get_pass_must_change_time(to) == 0) {
+ if (!pdb_get_account_policy(AP_MAX_PASSWORD_AGE, &expire)
+ || expire == (uint32)-1) {
+ new_time = get_time_t_max();
+ } else {
+ time_t old_time = pdb_get_pass_last_set_time(to);
+ new_time = old_time + expire;
+ if ((new_time) < time(0)) {
+ new_time = time(0) + expire;
+ }
+ }
+ if (!pdb_set_pass_must_change_time (to, new_time, PDB_CHANGED)) {
+ DEBUG (0, ("pdb_set_pass_must_change_time failed!\n"));
+ }
}
}
@@ -535,6 +587,14 @@ void copy_id25_to_sam_passwd(struct samu *to, SAM_USER_INFO_25 *from)
pdb_set_kickoff_time(to, unix_time , PDB_CHANGED);
}
+ if (from->fields_present & ACCT_ALLOW_PWD_CHANGE) {
+ unix_time=nt_time_to_unix(&from->pass_can_change_time);
+ stored_time = pdb_get_pass_can_change_time(to);
+ DEBUG(10,("INFO_25 PASS_CAN_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_can_change_time(to, unix_time, PDB_CHANGED);
+ }
+
if (from->fields_present & ACCT_LAST_PWD_CHANGE) {
unix_time=nt_time_to_unix(&from->pass_last_set_time);
stored_time = pdb_get_pass_last_set_time(to);
@@ -543,6 +603,14 @@ void copy_id25_to_sam_passwd(struct samu *to, SAM_USER_INFO_25 *from)
pdb_set_pass_last_set_time(to, unix_time, PDB_CHANGED);
}
+ if (from->fields_present & ACCT_FORCE_PWD_CHANGE) {
+ unix_time=nt_time_to_unix(&from->pass_must_change_time);
+ stored_time=pdb_get_pass_must_change_time(to);
+ DEBUG(10,("INFO_25 PASS_MUST_CH: %lu -> %lu\n",(long unsigned int)stored_time, (long unsigned int)unix_time));
+ if (stored_time != unix_time)
+ pdb_set_pass_must_change_time(to, unix_time, PDB_CHANGED);
+ }
+
if ((from->fields_present & ACCT_USERNAME) &&
(from->hdr_user_name.buffer)) {
old_string = pdb_get_username(to);
diff --git a/source/rpcclient/cmd_netlogon.c b/source/rpcclient/cmd_netlogon.c
index 35b8accdb6a..4608c6b3da3 100644
--- a/source/rpcclient/cmd_netlogon.c
+++ b/source/rpcclient/cmd_netlogon.c
@@ -45,21 +45,21 @@ static NTSTATUS cmd_netlogon_logon_ctrl2(struct rpc_pipe_client *cli,
return result;
}
-static NTSTATUS cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
- TALLOC_CTX *mem_ctx, int argc,
- const char **argv)
+static WERROR cmd_netlogon_getdcname(struct rpc_pipe_client *cli,
+ TALLOC_CTX *mem_ctx, int argc,
+ const char **argv)
{
fstring dcname;
- NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
+ WERROR result = WERR_GENERAL_FAILURE;
if (argc != 2) {
fprintf(stderr, "Usage: %s domainname\n", argv[0]);
- return NT_STATUS_OK;
+ return WERR_OK;
}
result = rpccli_netlogon_getdcname(cli, mem_ctx, cli->cli->desthost, argv[1], dcname);
- if (!NT_STATUS_IS_OK(result))
+ if (!W_ERROR_IS_OK(result))
goto done;
/* Display results */
@@ -369,7 +369,7 @@ struct cmd_set netlogon_commands[] = {
{ "NETLOGON" },
{ "logonctrl2", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl2, NULL, PI_NETLOGON, NULL, "Logon Control 2", "" },
- { "getdcname", RPC_RTYPE_NTSTATUS, cmd_netlogon_getdcname, NULL, PI_NETLOGON, NULL, "Get trusted DC name", "" },
+ { "getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_getdcname, PI_NETLOGON, NULL, "Get trusted DC name", "" },
{ "dsr_getdcname", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getdcname, PI_NETLOGON, NULL, "Get trusted DC name", "" },
{ "dsr_getsitename", RPC_RTYPE_WERROR, NULL, cmd_netlogon_dsr_getsitename, PI_NETLOGON, NULL, "Get sitename", "" },
{ "logonctrl", RPC_RTYPE_NTSTATUS, cmd_netlogon_logon_ctrl, NULL, PI_NETLOGON, NULL, "Logon Control", "" },
diff --git a/source/rpcclient/cmd_samr.c b/source/rpcclient/cmd_samr.c
index 1a204e70bc7..86ba20bb45c 100644
--- a/source/rpcclient/cmd_samr.c
+++ b/source/rpcclient/cmd_samr.c
@@ -785,6 +785,7 @@ static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
uint32 access_mask = MAXIMUM_ALLOWED_ACCESS;
int i;
fstring server;
+ unsigned int old_timeout;
if ((argc < 2) || (argc > 3)) {
printf("Usage: %s rid [access mask]\n", argv[0]);
@@ -819,10 +820,15 @@ static NTSTATUS cmd_samr_query_groupmem(struct rpc_pipe_client *cli,
if (!NT_STATUS_IS_OK(result))
goto done;
+ /* Make sure to wait for our DC's reply */
+ old_timeout = cli_set_timeout(cli->cli, 30000); /* 30 seconds. */
+
result = rpccli_samr_query_groupmem(cli, mem_ctx, &group_pol,
&num_members, &group_rids,
&group_attrs);
+ cli_set_timeout(cli->cli, old_timeout);
+
if (!NT_STATUS_IS_OK(result))
goto done;
diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c
index d6ba7bc2d55..902212eaf1c 100644
--- a/source/smbd/quotas.c
+++ b/source/smbd/quotas.c
@@ -587,7 +587,6 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
int file;
static struct mnttab mnt;
static pstring name;
- pstring devopt;
#else /* SunOS4 */
struct mntent *mnt;
static pstring name;
@@ -604,7 +603,8 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
return(False) ;
devno = sbuf.st_dev ;
- DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n", path,(unsigned int)devno));
+ DEBUG(5,("disk_quotas: looking for path \"%s\" devno=%x\n",
+ path, (unsigned int)devno));
if ( devno != devno_cached ) {
devno_cached = devno ;
#if defined(SUNOS5)
@@ -612,17 +612,19 @@ BOOL disk_quotas(const char *path, SMB_BIG_UINT *bsize, SMB_BIG_UINT *dfree, SMB
return(False) ;
found = False ;
- slprintf(devopt, sizeof(devopt) - 1, "dev=%x", (unsigned int)devno);
+
while (getmntent(fd, &mnt) == 0) {
- if( !hasmntopt(&mnt, devopt) )
+ if (sys_stat(mnt.mnt_mountp, &sbuf) == -1)
continue;
- DEBUG(5,("disk_quotas: testing \"%s\" %s\n", mnt.mnt_mountp,devopt));
+ DEBUG(5,("disk_quotas: testing \"%s\" devno=%x\n",
+ mnt.mnt_mountp, (unsigned int)devno));
/* quotas are only on vxfs, UFS or NFS */
- if ( strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 ||
+ if ( (sbuf.st_dev == devno) && (
+ strcmp( mnt.mnt_fstype, MNTTYPE_UFS ) == 0 ||
strcmp( mnt.mnt_fstype, "nfs" ) == 0 ||
- strcmp( mnt.mnt_fstype, "vxfs" ) == 0 ) {
+ strcmp( mnt.mnt_fstype, "vxfs" ) == 0 )) {
found = True ;
break;
}
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index 606e45100e8..4f45be5b634 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -273,6 +273,14 @@ retry:
status = ads_connect(ads);
if (!ADS_ERR_OK(status)) {
+
+ if (NT_STATUS_EQUAL(ads_ntstatus(status),
+ NT_STATUS_NO_LOGON_SERVERS)) {
+ DEBUG(0,("ads_connect: %s\n", ads_errstr(status)));
+ ads_destroy(&ads);
+ return status;
+ }
+
if (!need_password && !second_time) {
need_password = True;
second_time = True;
@@ -1426,7 +1434,8 @@ static int net_ads_printer_info(int argc, const char **argv)
rc = ads_find_printer_on_server(ads, &res, printername, servername);
if (!ADS_ERR_OK(rc)) {
- d_fprintf(stderr, "ads_find_printer_on_server: %s\n", ads_errstr(rc));
+ d_fprintf(stderr, "Server '%s' not found: %s\n",
+ servername, ads_errstr(rc));
ads_msgfree(ads, res);
ads_destroy(&ads);
return -1;
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index 05d2f1f6703..b29acc8a106 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -29,7 +29,7 @@
/* uid's and gid's for writing deltas to ldif */
static uint32 ldif_gid = 999;
static uint32 ldif_uid = 999;
-/* Kkeep track of ldap initialization */
+/* Keep track of ldap initialization */
static int init_ldap = 1;
static void display_group_mem_info(uint32 rid, SAM_GROUP_MEM_INFO *g)
@@ -1135,37 +1135,6 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
fflush(add_fd);
}
- /* Write the root entity */
- fprintf(add_fd, "# root, %s, %s\n", user_attr, suffix);
- fprintf(add_fd, "dn: uid=root,ou=%s,%s\n", user_attr, suffix);
- fprintf(add_fd, "cn: root\n");
- fprintf(add_fd, "sn: root\n");
- fprintf(add_fd, "objectClass: inetOrgPerson\n");
- fprintf(add_fd, "objectClass: sambaSAMAccount\n");
- fprintf(add_fd, "objectClass: posixAccount\n");
- fprintf(add_fd, "objectClass: shadowAccount\n");
- fprintf(add_fd, "gidNumber: 0\n");
- fprintf(add_fd, "uid: root\n");
- fprintf(add_fd, "uidNumber: 0\n");
- fprintf(add_fd, "homeDirectory: /home/root\n");
- fprintf(add_fd, "sambaPwdLastSet: 0\n");
- fprintf(add_fd, "sambaLogonTime: 0\n");
- fprintf(add_fd, "sambaLogoffTime: 2147483647\n");
- fprintf(add_fd, "sambaKickoffTime: 2147483647\n");
- fprintf(add_fd, "sambaPwdCanChange: 0\n");
- fprintf(add_fd, "sambaPwdMustChange: 2147483647\n");
- fprintf(add_fd, "sambaHomePath: \\\\PDC-SRV\root\n");
- fprintf(add_fd, "sambaHomeDrive: H:\n");
- fprintf(add_fd, "sambaProfilePath: \\\\PDC-SRV\\profiles\\root\n");
- fprintf(add_fd, "sambaprimaryGroupSID: %s-512\n", sid);
- fprintf(add_fd, "sambaLMPassword: XXX\n");
- fprintf(add_fd, "sambaNTPassword: XXX\n");
- fprintf(add_fd, "sambaAcctFlags: [U\n");
- fprintf(add_fd, "sambaSID: %s-500\n", sid);
- fprintf(add_fd, "loginShell: /bin/false\n");
- fprintf(add_fd, "\n");
- fflush(add_fd);
-
/* Write the domain entity */
fprintf(add_fd, "# %s, %s\n", lp_workgroup(), suffix);
fprintf(add_fd, "dn: sambaDomainName=%s,%s\n", lp_workgroup(),
@@ -1179,37 +1148,6 @@ static NTSTATUS populate_ldap_for_ldif(fstring sid, const char *suffix, const ch
fprintf(add_fd, "\n");
fflush(add_fd);
- /* Write user nobody entity */
- fprintf(add_fd, "# nobody, %s, %s\n", user_attr, suffix);
- fprintf(add_fd, "dn: uid=nobody,ou=%s,%s\n", user_attr, suffix);
- fprintf(add_fd, "cn: nobody\n");
- fprintf(add_fd, "sn: nobody\n");
- fprintf(add_fd, "objectClass: inetOrgPerson\n");
- fprintf(add_fd, "objectClass: sambaSAMAccount\n");
- fprintf(add_fd, "objectClass: posixAccount\n");
- fprintf(add_fd, "objectClass: shadowAccount\n");
- fprintf(add_fd, "gidNumber: 514\n");
- fprintf(add_fd, "uid: nobody\n");
- fprintf(add_fd, "uidNumber: 999\n");
- fprintf(add_fd, "homeDirectory: /nobodyshomedir\n");
- fprintf(add_fd, "sambaPwdLastSet: 0\n");
- fprintf(add_fd, "sambaLogonTime: 0\n");
- fprintf(add_fd, "sambaLogoffTime: 2147483647\n");
- fprintf(add_fd, "sambaKickoffTime: 2147483647\n");
- fprintf(add_fd, "sambaPwdCanChange: 0\n");
- fprintf(add_fd, "sambaPwdMustChange: 2147483647\n");
- fprintf(add_fd, "sambaHomePath: \\\\PDC-SMD3\\homes\\nobody\n");
- fprintf(add_fd, "sambaHomeDrive: H:\n");
- fprintf(add_fd, "sambaProfilePath: \\\\PDC-SMB3\\profiles\\nobody\n");
- fprintf(add_fd, "sambaprimaryGroupSID: %s-514\n", sid);
- fprintf(add_fd, "sambaLMPassword: NOPASSWORDXXXXXXXXXXXXXXXXXXXXX\n");
- fprintf(add_fd, "sambaNTPassword: NOPASSWORDXXXXXXXXXXXXXXXXXXXXX\n");
- fprintf(add_fd, "sambaAcctFlags: [NU\n");
- fprintf(add_fd, "sambaSID: %s-2998\n", sid);
- fprintf(add_fd, "loginShell: /bin/false\n");
- fprintf(add_fd, "\n");
- fflush(add_fd);
-
/* Write the Domain Admins entity */
fprintf(add_fd, "# Domain Admins, %s, %s\n", group_attr,
suffix);
diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c
index 4c1b967d4e4..654c9ec5b2a 100644
--- a/source/utils/net_sam.c
+++ b/source/utils/net_sam.c
@@ -206,20 +206,23 @@ static int net_sam_set_pwnoexp(int argc, const char **argv)
}
/*
- * Set pass last change time, based on force pass change now
+ * Set a user's time field
*/
-static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
+static int net_sam_set_time(int argc, const char **argv, const char *field,
+ BOOL (*fn)(struct samu *, time_t,
+ enum pdb_value_state))
{
struct samu *sam_acct = NULL;
DOM_SID sid;
enum SID_NAME_USE type;
const char *dom, *name;
NTSTATUS status;
+ time_t new_time;
- if ((argc != 2) || (!strequal(argv[1], "yes") &&
- !strequal(argv[1], "no"))) {
- d_fprintf(stderr, "usage: net sam set pwdmustchangenow <user> [yes|no]\n");
+ if (argc != 2) {
+ d_fprintf(stderr, "usage: net sam set %s <user> "
+ "[now|YYYY-MM-DD HH:MM]\n", field);
return -1;
}
@@ -235,6 +238,22 @@ static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
return -1;
}
+ if (strequal(argv[1], "now")) {
+ new_time = time(NULL);
+ } else {
+ struct tm tm;
+ char *end;
+ ZERO_STRUCT(tm);
+ end = strptime(argv[1], "%Y-%m-%d %H:%M", &tm);
+ new_time = mktime(&tm);
+ if ((end == NULL) || (*end != '\0') || (new_time == -1)) {
+ d_fprintf(stderr, "Could not parse time string %s\n",
+ argv[1]);
+ return -1;
+ }
+ }
+
+
if ( !(sam_acct = samu_new( NULL )) ) {
d_fprintf(stderr, "Internal error\n");
return -1;
@@ -245,10 +264,9 @@ static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
return -1;
}
- if (strequal(argv[1], "yes")) {
- pdb_set_pass_last_set_time(sam_acct, 0, PDB_CHANGED);
- } else {
- pdb_set_pass_last_set_time(sam_acct, time(NULL), PDB_CHANGED);
+ if (!fn(sam_acct, new_time, PDB_CHANGED)) {
+ d_fprintf(stderr, "Internal error\n");
+ return -1;
}
status = pdb_update_sam_account(sam_acct);
@@ -260,11 +278,21 @@ static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
TALLOC_FREE(sam_acct);
- d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", dom,
- name, argv[1]);
+ d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]);
return 0;
}
+static int net_sam_set_pwdmustchange(int argc, const char **argv)
+{
+ return net_sam_set_time(argc, argv, "pwdmustchange",
+ pdb_set_pass_must_change_time);
+}
+
+static int net_sam_set_pwdcanchange(int argc, const char **argv)
+{
+ return net_sam_set_time(argc, argv, "pwdcanchange",
+ pdb_set_pass_can_change_time);
+}
/*
* Set a user's or a group's comment
@@ -348,8 +376,10 @@ static int net_sam_set(int argc, const char **argv)
"Disable/Enable a user's lockout flag" },
{ "pwnoexp", net_sam_set_pwnoexp,
"Disable/Enable whether a user's pw does not expire" },
- { "pwdmustchangenow", net_sam_set_pwdmustchangenow,
- "Force users password must change at next logon" },
+ { "pwdmustchange", net_sam_set_pwdmustchange,
+ "Set a users password must change time" },
+ { "pwdcanchange", net_sam_set_pwdcanchange,
+ "Set a users password can change time" },
{NULL, NULL}
};
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index db8661ecad5..0a6fb7e8bec 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -419,7 +419,8 @@ static int set_user_info (struct pdb_methods *in, const char *username,
const char *drive, const char *script,
const char *profile, const char *account_control,
const char *user_sid, const char *user_domain,
- const BOOL badpw, const BOOL hours)
+ const BOOL badpw, const BOOL hours,
+ time_t pwd_can_change, time_t pwd_must_change)
{
BOOL updated_autolock = False, updated_badpw = False;
struct samu *sam_pwent=NULL;
@@ -446,6 +447,14 @@ static int set_user_info (struct pdb_methods *in, const char *username,
pdb_set_hours(sam_pwent, hours_array, PDB_CHANGED);
}
+ if (pwd_can_change != -1) {
+ pdb_set_pass_can_change_time(sam_pwent, pwd_can_change, PDB_CHANGED);
+ }
+
+ if (pwd_must_change != -1) {
+ pdb_set_pass_must_change_time(sam_pwent, pwd_must_change, PDB_CHANGED);
+ }
+
if (!pdb_update_autolock_flag(sam_pwent, &updated_autolock)) {
DEBUG(2,("pdb_update_autolock_flag failed.\n"));
}
@@ -769,6 +778,8 @@ int main (int argc, char **argv)
BOOL account_policy_value_set = False;
static BOOL badpw_reset = False;
static BOOL hours_reset = False;
+ static char *pwd_can_change_time = NULL;
+ static char *pwd_must_change_time = NULL;
static char *pwd_time_format = NULL;
static BOOL pw_from_stdin = False;
struct pdb_methods *bin, *bout, *bdef;
@@ -803,6 +814,8 @@ int main (int argc, char **argv)
{"force-initialized-passwords", 0, POPT_ARG_NONE, &force_initialised_password, 0, "Force initialization of corrupt password strings in a passdb backend", NULL},
{"bad-password-count-reset", 'z', POPT_ARG_NONE, &badpw_reset, 0, "reset bad password count", NULL},
{"logon-hours-reset", 'Z', POPT_ARG_NONE, &hours_reset, 0, "reset logon hours", NULL},
+ {"pwd-can-change-time", 0, POPT_ARG_STRING, &pwd_can_change_time, 0, "Set password can change time (unix time in seconds since 1970 if time format not provided)", NULL },
+ {"pwd-must-change-time", 0, POPT_ARG_STRING, &pwd_must_change_time, 0, "Set password must change time (unix time in seconds since 1970 if time format not provided)", NULL },
{"time-format", 0, POPT_ARG_STRING, &pwd_time_format, 0, "The time format for time parameters", NULL },
{"password-from-stdin", 't', POPT_ARG_NONE, &pw_from_stdin, 0, "get password from standard in", NULL},
POPT_COMMON_SAMBA
@@ -865,7 +878,9 @@ int main (int argc, char **argv)
(backend_in ? BIT_IMPORT : 0) +
(backend_out ? BIT_EXPORT : 0) +
(badpw_reset ? BIT_BADPWRESET : 0) +
- (hours_reset ? BIT_LOGONHOURS : 0);
+ (hours_reset ? BIT_LOGONHOURS : 0) +
+ (pwd_can_change_time ? BIT_CAN_CHANGE: 0) +
+ (pwd_must_change_time ? BIT_MUST_CHANGE: 0);
if (setparms & BIT_BACKEND) {
if (!NT_STATUS_IS_OK(make_pdb_method_name( &bdef, backend ))) {
@@ -1037,9 +1052,67 @@ int main (int argc, char **argv)
/* account modification operations */
if (!(checkparms & ~(BIT_MODIFY + BIT_USER))) {
+ time_t pwd_can_change = -1;
+ time_t pwd_must_change = -1;
+ const char *errstr;
+
+ if (pwd_can_change_time) {
+ errstr = "can";
+ if (pwd_time_format) {
+ struct tm tm;
+ char *ret;
+
+ memset(&tm, 0, sizeof(struct tm));
+ ret = strptime(pwd_can_change_time, pwd_time_format, &tm);
+ if (ret == NULL || *ret != '\0') {
+ goto error;
+ }
+
+ pwd_can_change = mktime(&tm);
+
+ if (pwd_can_change == -1) {
+ goto error;
+ }
+ } else { /* assume it is unix time */
+ errno = 0;
+ pwd_can_change = strtol(pwd_can_change_time, NULL, 10);
+ if (errno) {
+ goto error;
+ }
+ }
+ }
+ if (pwd_must_change_time) {
+ errstr = "must";
+ if (pwd_time_format) {
+ struct tm tm;
+ char *ret;
+
+ memset(&tm, 0, sizeof(struct tm));
+ ret = strptime(pwd_must_change_time, pwd_time_format, &tm);
+ if (ret == NULL || *ret != '\0') {
+ goto error;
+ }
+
+ pwd_must_change = mktime(&tm);
+
+ if (pwd_must_change == -1) {
+ goto error;
+ }
+ } else { /* assume it is unix time */
+ errno = 0;
+ pwd_must_change = strtol(pwd_must_change_time, NULL, 10);
+ if (errno) {
+ goto error;
+ }
+ }
+ }
return set_user_info (bdef, user_name, full_name, home_dir,
acct_desc, home_drive, logon_script, profile_path, account_control,
- user_sid, user_domain, badpw_reset, hours_reset);
+ user_sid, user_domain, badpw_reset, hours_reset, pwd_can_change,
+ pwd_must_change);
+error:
+ fprintf (stderr, "Error parsing the time in pwd-%s-change-time!\n", errstr);
+ return -1;
}
}