diff options
author | Gerald Carter <jerry@samba.org> | 2006-10-26 14:57:11 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2006-10-26 14:57:11 +0000 |
commit | 47dde11977c259e804ae67f1507d0e2f7e8263fc (patch) | |
tree | 68f478569486c25986b003fd62b5b0d40819435f /source | |
parent | 6cd6987fc504a8056295113c12f629ad5c4b2868 (diff) | |
download | samba-47dde11977c259e804ae67f1507d0e2f7e8263fc.tar.gz samba-47dde11977c259e804ae67f1507d0e2f7e8263fc.tar.xz samba-47dde11977c259e804ae67f1507d0e2f7e8263fc.zip |
r19499: sync up changes for 3.0.23d
Diffstat (limited to 'source')
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; } } |