summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-10-01 21:20:14 +0000
committerGerald Carter <jerry@samba.org>2006-10-01 21:20:14 +0000
commit6cd6987fc504a8056295113c12f629ad5c4b2868 (patch)
tree1cb4088f4b88d086f5b0bc84ffa99aa3c537e0b2 /source
parent2f4cccbf3b63db498bde48679c228747f1838f91 (diff)
downloadsamba-6cd6987fc504a8056295113c12f629ad5c4b2868.tar.gz
samba-6cd6987fc504a8056295113c12f629ad5c4b2868.tar.xz
samba-6cd6987fc504a8056295113c12f629ad5c4b2868.zip
r19018: staging for a 3.0.23d on Tuesday (I think we have sufficient changes to warrant one)
Diffstat (limited to 'source')
-rw-r--r--source/Makefile.in18
-rw-r--r--source/VERSION2
-rw-r--r--source/auth/auth_util.c1
-rw-r--r--source/configure.in1
-rw-r--r--source/groupdb/mapping.c17
-rw-r--r--source/include/includes.h8
-rw-r--r--source/lib/account_pol.c7
-rw-r--r--source/lib/util.c32
-rw-r--r--source/lib/util_sec.c42
-rw-r--r--source/libads/cldap.c3
-rw-r--r--source/libads/ldap.c9
-rw-r--r--source/libads/ldap_schema.c23
-rw-r--r--source/libads/ldap_utils.c25
-rw-r--r--source/libsmb/ntlmssp.c19
-rw-r--r--source/libsmb/smbencrypt.c6
-rw-r--r--source/nsswitch/winbindd.c3
-rw-r--r--source/nsswitch/winbindd_async.c116
-rw-r--r--source/nsswitch/winbindd_cache.c9
-rw-r--r--source/nsswitch/winbindd_dual.c7
-rw-r--r--source/nsswitch/winbindd_group.c104
-rw-r--r--source/nsswitch/winbindd_nss.h2
-rw-r--r--source/nsswitch/winbindd_pam.c2
-rw-r--r--source/nsswitch/winbindd_sid.c47
-rw-r--r--source/nsswitch/winbindd_user.c32
-rw-r--r--source/nsswitch/winbindd_util.c26
-rw-r--r--source/passdb/lookup_sid.c41
-rw-r--r--source/passdb/pdb_get_set.c26
-rw-r--r--source/passdb/pdb_interface.c6
-rw-r--r--source/passdb/pdb_ldap.c4
-rw-r--r--source/passdb/pdb_smbpasswd.c4
-rw-r--r--source/passdb/pdb_tdb.c4
-rw-r--r--source/rpc_parse/parse_samr.c15
-rw-r--r--source/rpc_server/srv_samr_util.c108
-rw-r--r--source/rpc_server/srv_spoolss_nt.c3
-rw-r--r--source/smbd/dir.c91
-rw-r--r--source/smbd/sesssetup.c2
-rw-r--r--source/smbd/share_access.c4
-rw-r--r--source/smbd/trans2.c10
-rw-r--r--source/utils/net_ads.c9
-rw-r--r--source/utils/net_rpc_samsync.c3
-rw-r--r--source/utils/net_sam.c56
-rw-r--r--source/utils/net_usershare.c68
-rw-r--r--source/utils/ntlm_auth.c37
-rw-r--r--source/utils/pdbedit.c79
44 files changed, 720 insertions, 411 deletions
diff --git a/source/Makefile.in b/source/Makefile.in
index 127936125bf..1c740ed71b4 100644
--- a/source/Makefile.in
+++ b/source/Makefile.in
@@ -341,7 +341,7 @@ PASSDB_OBJ = $(PASSDB_GET_SET_OBJ) passdb/passdb.o passdb/pdb_interface.o \
passdb/util_wellknown.o passdb/util_builtin.o passdb/pdb_compat.o \
passdb/util_unixsids.o passdb/lookup_sid.o \
passdb/login_cache.o @PDB_STATIC@ \
- lib/account_pol.o lib/privileges.o
+ lib/account_pol.o lib/privileges.o lib/util_nscd.o
DEVEL_HELP_WEIRD_OBJ = modules/weird.o
CP850_OBJ = modules/CP850.o
@@ -910,7 +910,7 @@ bin/smbd@EXEEXT@: $(SMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBD_OBJ) $(LDFLAGS) $(LDAP_LIBS) \
$(KRB5LIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) \
- $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ @SMBD_LIBS@
+ $(ACL_LIBS) $(PASSDB_LIBS) $(LIBS) @POPTLIBS@ @SMBD_LIBS@
bin/nmbd@EXEEXT@: $(NMBD_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -997,7 +997,7 @@ bin/pdbedit@EXEEXT@: $(PDBEDIT_OBJ) @BUILD_POPT@ bin/.dummy
bin/smbget@EXEEXT@: $(SMBGET_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBGET_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS)
bin/samtest@EXEEXT@: $(SAMTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -1025,11 +1025,13 @@ bin/msgtest@EXEEXT@: $(MSGTEST_OBJ) bin/.dummy
bin/smbcacls@EXEEXT@: $(SMBCACLS_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCACLS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ \
+ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS)
bin/smbcquotas@EXEEXT@: $(SMBCQUOTAS_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(SMBCQUOTAS_OBJ) $(DYNEXP) $(LDFLAGS) $(LIBS) @POPTLIBS@ \
+ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS)
bin/eventlogadm@EXEEXT@: $(EVTLOGADM_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -1045,7 +1047,7 @@ bin/nsstest@EXEEXT@: $(NSSTEST_OBJ) bin/.dummy
bin/vfstest@EXEEXT@: $(VFSTEST_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
- @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) @SMBD_LIBS@
+ @$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(VFSTEST_OBJ) $(LDFLAGS) $(TERMLDFLAGS) $(TERMLIBS) $(DYNEXP) $(PRINT_LIBS) $(AUTH_LIBS) $(ACL_LIBS) $(LIBS) @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) @SMBD_LIBS@ $(NSCD_LIBS)
bin/smbiconv@EXEEXT@: $(SMBICONV_OBJ) @BUILD_POPT@ bin/.dummy
@echo Linking $@
@@ -1199,7 +1201,7 @@ bin/librpc_echo.@SHLIBEXT@: $(RPC_ECHO_OBJ)
bin/winbindd@EXEEXT@: $(WINBINDD_OBJ) @BUILD_POPT@ bin/.dummy
@echo "Linking $@"
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(WINBINDD_OBJ) $(LDFLAGS) $(DYNEXP) $(LIBS) \
- @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS) $(NSCD_LIBS)
+ @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(PASSDB_LIBS)
# Please don't add .o files to libnss_winbind, libnss_wins, or the pam_winbind
# libraries. Add to the appropriate PICOBJ variable instead.
@@ -1368,7 +1370,7 @@ bin/ntlm_auth@EXEEXT@: $(NTLM_AUTH_OBJ) $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) \
@echo Linking $@
@$(CC) $(FLAGS) @PIE_LDFLAGS@ -o $@ $(LDFLAGS) $(DYNEXP) $(NTLM_AUTH_OBJ) \
$(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(LIBS) \
- @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS)
+ @POPTLIBS@ $(KRB5LIBS) $(LDAP_LIBS) $(NSCD_LIBS)
bin/pam_smbpass.@SHLIBEXT@: $(PAM_SMBPASS_PICOOBJ)
@echo "Linking shared library $@"
diff --git a/source/VERSION b/source/VERSION
index e2a79b8b99c..8a11e1420fa 100644
--- a/source/VERSION
+++ b/source/VERSION
@@ -37,7 +37,7 @@ SAMBA_VERSION_RELEASE=23
# e.g. SAMBA_VERSION_REVISION=a #
# -> "2.2.8a" #
########################################################
-SAMBA_VERSION_REVISION=c
+SAMBA_VERSION_REVISION=d
########################################################
# For 'pre' releases the version will be #
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index 507b3c725be..704f0989e3a 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -1202,6 +1202,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
num_group_sids = 1;
group_sids = &primary_group_sid;
+ gids = gid;
*found_username = talloc_strdup(mem_ctx, username);
}
diff --git a/source/configure.in b/source/configure.in
index 6db439c0d35..a2a733a61d2 100644
--- a/source/configure.in
+++ b/source/configure.in
@@ -3817,6 +3817,7 @@ LIBS="$ac_save_LIBS"
fi
AC_CHECK_LIB_EXT(nscd, NSCD_LIBS, nscd_flush_cache)
+PASSDB_LIBS="$PASSDB_LIBS $NSCD_LIBS"
#################################################
# check for automount support
diff --git a/source/groupdb/mapping.c b/source/groupdb/mapping.c
index b1c5275bc10..902068204ac 100644
--- a/source/groupdb/mapping.c
+++ b/source/groupdb/mapping.c
@@ -878,9 +878,12 @@ int smb_create_group(const char *unix_group, gid_t *new_gid)
pstring_sub(add_script, "%g", unix_group);
ret = smbrun(add_script, &fd);
DEBUG(ret ? 0 : 3,("smb_create_group: Running the command `%s' gave %d\n",add_script,ret));
+ if (ret == 0) {
+ smb_nscd_flush_group_cache();
+ }
if (ret != 0)
return ret;
-
+
if (fd != 0) {
fstring output;
@@ -920,6 +923,9 @@ int smb_delete_group(const char *unix_group)
pstring_sub(del_script, "%g", unix_group);
ret = smbrun(del_script,NULL);
DEBUG(ret ? 0 : 3,("smb_delete_group: Running the command `%s' gave %d\n",del_script,ret));
+ if (ret == 0) {
+ smb_nscd_flush_group_cache();
+ }
return ret;
}
@@ -944,6 +950,9 @@ int smb_set_primary_group(const char *unix_group, const char* unix_user)
flush_pwnam_cache();
DEBUG(ret ? 0 : 3,("smb_set_primary_group: "
"Running the command `%s' gave %d\n",add_script,ret));
+ if (ret == 0) {
+ smb_nscd_flush_group_cache();
+ }
return ret;
}
@@ -967,6 +976,9 @@ int smb_add_user_group(const char *unix_group, const char *unix_user)
pstring_sub(add_script, "%u", unix_user);
ret = smbrun(add_script,NULL);
DEBUG(ret ? 0 : 3,("smb_add_user_group: Running the command `%s' gave %d\n",add_script,ret));
+ if (ret == 0) {
+ smb_nscd_flush_group_cache();
+ }
return ret;
}
@@ -990,6 +1002,9 @@ int smb_delete_user_group(const char *unix_group, const char *unix_user)
pstring_sub(del_script, "%u", unix_user);
ret = smbrun(del_script,NULL);
DEBUG(ret ? 0 : 3,("smb_delete_user_group: Running the command `%s' gave %d\n",del_script,ret));
+ if (ret == 0) {
+ smb_nscd_flush_group_cache();
+ }
return ret;
}
diff --git a/source/include/includes.h b/source/include/includes.h
index 81e772b3a48..0d456a7ce48 100644
--- a/source/include/includes.h
+++ b/source/include/includes.h
@@ -1450,6 +1450,10 @@ int smb_xvasprintf(char **ptr, const char *format, va_list ap) PRINTF_ATTRIBUTE(
#endif
#endif
+#ifndef HAVE_VSYSLOG
+void vsyslog (int facility_priority, const char *format, va_list arglist);
+#endif
+
#ifndef HAVE_TIMEGM
time_t timegm(struct tm *tm);
#endif
@@ -1600,4 +1604,8 @@ void exit_server(const char *const reason) NORETURN_ATTRIBUTE ;
void exit_server_cleanly(const char *const reason) NORETURN_ATTRIBUTE ;
void exit_server_fault(void) NORETURN_ATTRIBUTE ;
+#ifdef HAVE_LIBNSCD
+#include "libnscd.h"
+#endif
+
#endif /* _INCLUDES_H */
diff --git a/source/lib/account_pol.c b/source/lib/account_pol.c
index 6bf7346fe7f..d4e585f74f6 100644
--- a/source/lib/account_pol.c
+++ b/source/lib/account_pol.c
@@ -295,8 +295,11 @@ BOOL init_account_policy(void)
/* BUILTIN\Administrators get everything -- *always* */
- if ( !grant_all_privileges( &global_sid_Builtin_Administrators ) ) {
- DEBUG(0,("init_account_policy: Failed to grant privileges to BUILTIN\\Administrators!\n"));
+ if ( lp_enable_privileges() ) {
+ if ( !grant_all_privileges( &global_sid_Builtin_Administrators ) ) {
+ DEBUG(1,("init_account_policy: Failed to grant privileges "
+ "to BUILTIN\\Administrators!\n"));
+ }
}
return True;
diff --git a/source/lib/util.c b/source/lib/util.c
index a1efecfbbba..12be5bc6c04 100644
--- a/source/lib/util.c
+++ b/source/lib/util.c
@@ -2828,9 +2828,36 @@ BOOL unix_wild_match(const char *pattern, const char *string)
void name_to_fqdn(fstring fqdn, const char *name)
{
struct hostent *hp = sys_gethostbyname(name);
+
if ( hp && hp->h_name && *hp->h_name ) {
- DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, hp->h_name));
- fstrcpy(fqdn,hp->h_name);
+ char *full = NULL;
+
+ /* find out if the fqdn is returned as an alias
+ * to cope with /etc/hosts files where the first
+ * name is not the fqdn but the short name */
+ if (hp->h_aliases && (! strchr_m(hp->h_name, '.'))) {
+ int i;
+ for (i = 0; hp->h_aliases[i]; i++) {
+ if (strchr_m(hp->h_aliases[i], '.')) {
+ full = hp->h_aliases[i];
+ break;
+ }
+ }
+ }
+ if (full && (StrCaseCmp(full, "localhost.localdomain") == 0)) {
+ DEBUG(1, ("WARNING: your /etc/hosts file may be broken!\n"));
+ DEBUGADD(1, (" Specifing the machine hostname for address 127.0.0.1 may lead\n"));
+ DEBUGADD(1, (" to Kerberos authentication probelms as localhost.localdomain\n"));
+ DEBUGADD(1, (" may end up being used instead of the real machine FQDN.\n"));
+ full = hp->h_name;
+ }
+
+ if (!full) {
+ full = hp->h_name;
+ }
+
+ DEBUG(10,("name_to_fqdn: lookup for %s -> %s.\n", name, full));
+ fstrcpy(fqdn, full);
} else {
DEBUG(10,("name_to_fqdn: lookup for %s failed.\n", name));
fstrcpy(fqdn, name);
@@ -2987,4 +3014,3 @@ int this_is_smp(void)
return 0;
#endif
}
-
diff --git a/source/lib/util_sec.c b/source/lib/util_sec.c
index 26be27ea515..3f8cb690cd0 100644
--- a/source/lib/util_sec.c
+++ b/source/lib/util_sec.c
@@ -52,10 +52,16 @@ static gid_t initial_gid;
remember what uid we got started as - this allows us to run correctly
as non-root while catching trapdoor systems
****************************************************************************/
+
void sec_init(void)
{
- initial_uid = geteuid();
- initial_gid = getegid();
+ static int initialized;
+
+ if (!initialized) {
+ initial_uid = geteuid();
+ initial_gid = getegid();
+ initialized = 1;
+ }
}
/****************************************************************************
@@ -252,10 +258,9 @@ void save_re_uid(void)
/****************************************************************************
and restore them!
****************************************************************************/
-void restore_re_uid(void)
-{
- set_effective_uid(0);
+static void restore_re_uid_fromroot(void)
+{
#if USE_SETRESUID
setresuid(saved_ruid, saved_euid, -1);
#elif USE_SETREUID
@@ -274,6 +279,33 @@ void restore_re_uid(void)
assert_uid(saved_ruid, saved_euid);
}
+void restore_re_uid(void)
+{
+ set_effective_uid(0);
+ restore_re_uid_fromroot();
+}
+
+/****************************************************************************
+ Lightweight become root - no group change.
+****************************************************************************/
+
+void become_root_uid_only(void)
+{
+ save_re_uid();
+ set_effective_uid(0);
+}
+
+/****************************************************************************
+ Lightweight unbecome root - no group change. Expects we are root already,
+ saves errno across call boundary.
+****************************************************************************/
+
+void unbecome_root_uid_only(void)
+{
+ int saved_errno = errno;
+ restore_re_uid_fromroot();
+ errno = saved_errno;
+}
/****************************************************************************
save the real and effective gid for later restoration. Used by the
diff --git a/source/libads/cldap.c b/source/libads/cldap.c
index 2e96270e906..174064464f9 100644
--- a/source/libads/cldap.c
+++ b/source/libads/cldap.c
@@ -160,6 +160,8 @@ static int send_cldap_netlogon(int sock, const char *domain,
if (write(sock, data.data, data.length) != (ssize_t)data.length) {
DEBUG(2,("failed to send cldap query (%s)\n", strerror(errno)));
+ asn1_free(&data);
+ return -1;
}
asn1_free(&data);
@@ -295,6 +297,7 @@ BOOL ads_cldap_netlogon(const char *server, const char *realm, struct cldap_net
ret = send_cldap_netlogon(sock, realm, global_myname(), 6);
if (ret != 0) {
+ close(sock);
return False;
}
ret = recv_cldap_netlogon(sock, reply);
diff --git a/source/libads/ldap.c b/source/libads/ldap.c
index c49e3480b80..ee60063a88f 100644
--- a/source/libads/ldap.c
+++ b/source/libads/ldap.c
@@ -2183,10 +2183,15 @@ ADS_STATUS ads_USN(ADS_STRUCT *ads, uint32 *usn)
return status;
if (ads_count_replies(ads, res) != 1) {
+ ads_msgfree(ads, res);
return ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
}
- ads_pull_uint32(ads, res, "highestCommittedUSN", usn);
+ if (!ads_pull_uint32(ads, res, "highestCommittedUSN", usn)) {
+ ads_msgfree(ads, res);
+ return ADS_ERROR(LDAP_NO_SUCH_ATTRIBUTE);
+ }
+
ads_msgfree(ads, res);
return ADS_SUCCESS;
}
@@ -2248,7 +2253,7 @@ ADS_STATUS ads_current_time(ADS_STRUCT *ads)
timestr = ads_pull_string(ads_s, ctx, res, "currentTime");
if (!timestr) {
- ads_msgfree(ads, res);
+ ads_msgfree(ads_s, res);
status = ADS_ERROR(LDAP_NO_RESULTS_RETURNED);
goto done;
}
diff --git a/source/libads/ldap_schema.c b/source/libads/ldap_schema.c
index b65ff956ac9..e63a888b5b9 100644
--- a/source/libads/ldap_schema.c
+++ b/source/libads/ldap_schema.c
@@ -181,7 +181,7 @@ static ADS_STATUS ads_schema_path(ADS_STRUCT *ads, TALLOC_CTX *mem_ctx, char **s
* Check for "Services for Unix" or rfc2307 Schema and load some attributes into the ADS_STRUCT
* @param ads connection to ads server
* @param enum mapping type
- * @return BOOL status of search (False if one or more attributes couldn't be
+ * @return ADS_STATUS status of search (False if one or more attributes couldn't be
* found in Active Directory)
**/
ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping map_type)
@@ -191,7 +191,6 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping
char **oids_out, **names_out;
size_t num_names;
char *schema_path = NULL;
- ADS_STRUCT *ads_s = ads;
int i;
const char *oids_sfu[] = { ADS_ATTR_SFU_UIDNUMBER_OID,
@@ -236,22 +235,6 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping
return ADS_ERROR(LDAP_NO_MEMORY);
}
- /* establish a new ldap tcp session if necessary */
-
- if (!ads->ld) {
- if ((ads_s = ads_init(ads->server.realm, ads->server.workgroup,
- ads->server.ldap_server)) == NULL) {
- status = ADS_ERROR(LDAP_SERVER_DOWN);
- goto done;
- }
-
- ads_s->auth.flags = ADS_AUTH_ANON_BIND;
- status = ads_connect(ads_s);
- if (!ADS_ERR_OK(status)) {
- goto done;
- }
- }
-
status = ads_schema_path(ads, ctx, &schema_path);
if (!ADS_ERR_OK(status)) {
DEBUG(3,("ads_check_posix_mapping: Unable to retrieve schema DN!\n"));
@@ -321,10 +304,6 @@ ADS_STATUS ads_check_posix_schema_mapping(ADS_STRUCT *ads, enum wb_posix_mapping
ads->schema.map_type = map_type;
done:
- /* free any temporary ads connections */
- if (ads_s != ads) {
- ads_destroy(&ads_s);
- }
if (ctx) {
talloc_destroy(ctx);
}
diff --git a/source/libads/ldap_utils.c b/source/libads/ldap_utils.c
index c3074233e2e..03ae94150f4 100644
--- a/source/libads/ldap_utils.c
+++ b/source/libads/ldap_utils.c
@@ -49,7 +49,15 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
}
*res = NULL;
- status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res);
+
+ /* when binding anonymously, we cannot use the paged search LDAP
+ * control - Guenther */
+
+ if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
+ status = ads_do_search(ads, bp, scope, expr, attrs, res);
+ } else {
+ status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res);
+ }
if (ADS_ERR_OK(status)) {
DEBUG(5,("Search for %s gave %d replies\n",
expr, ads_count_replies(ads, *res)));
@@ -82,10 +90,19 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
}
*res = NULL;
- status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res);
+
+ /* when binding anonymously, we cannot use the paged search LDAP
+ * control - Guenther */
+
+ if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
+ status = ads_do_search(ads, bp, scope, expr, attrs, res);
+ } else {
+ status = ads_do_search_all_args(ads, bp, scope, expr, attrs, args, res);
+ }
+
if (ADS_ERR_OK(status)) {
- DEBUG(5,("Search for %s gave %d replies\n",
- expr, ads_count_replies(ads, *res)));
+ DEBUG(5,("Search for filter: %s, base: %s gave %d replies\n",
+ expr, bp, ads_count_replies(ads, *res)));
SAFE_FREE(bp);
return status;
}
diff --git a/source/libsmb/ntlmssp.c b/source/libsmb/ntlmssp.c
index 986fa8cce9f..78292ed56f0 100644
--- a/source/libsmb/ntlmssp.c
+++ b/source/libsmb/ntlmssp.c
@@ -746,16 +746,25 @@ static NTSTATUS ntlmssp_server_auth(struct ntlmssp_state *ntlmssp_state,
if (lm_session_key.data && lm_session_key.length >= 8) {
if (ntlmssp_state->lm_resp.data && ntlmssp_state->lm_resp.length == 24) {
session_key = data_blob_talloc(ntlmssp_state->mem_ctx, NULL, 16);
+ if (session_key.data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
SMBsesskeygen_lm_sess_key(lm_session_key.data, ntlmssp_state->lm_resp.data,
session_key.data);
DEBUG(10,("ntlmssp_server_auth: Created NTLM session key.\n"));
- dump_data_pw("LM session key:\n", session_key.data, session_key.length);
} else {
- /* use the key unmodified - it's
- * probably a NULL key from the guest
- * login */
- session_key = lm_session_key;
+ static const uint8 zeros[24] = { 0, };
+ session_key = data_blob_talloc(
+ ntlmssp_state->mem_ctx, NULL, 16);
+ if (session_key.data == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ SMBsesskeygen_lm_sess_key(
+ lm_session_key.data, zeros,
+ session_key.data);
}
+ dump_data_pw("LM session key:\n", session_key.data,
+ session_key.length);
} else {
DEBUG(10,("ntlmssp_server_auth: Failed to create NTLM session key.\n"));
session_key = data_blob(NULL, 0);
diff --git a/source/libsmb/smbencrypt.c b/source/libsmb/smbencrypt.c
index ddfe696b48e..f285cdd3084 100644
--- a/source/libsmb/smbencrypt.c
+++ b/source/libsmb/smbencrypt.c
@@ -464,6 +464,9 @@ BOOL encode_pw_buffer(uint8 buffer[516], const char *password, int string_flags)
uchar new_pw[512];
size_t new_pw_len;
+ /* the incoming buffer can be any alignment. */
+ string_flags |= STR_NOALIGN;
+
new_pw_len = push_string(NULL, new_pw,
password,
sizeof(new_pw), string_flags);
@@ -494,6 +497,9 @@ BOOL decode_pw_buffer(uint8 in_buffer[516], char *new_pwrd,
{
int byte_len=0;
+ /* the incoming buffer can be any alignment. */
+ string_flags |= STR_NOALIGN;
+
/*
Warning !!! : This function is called from some rpc call.
The password IN the buffer may be a UNICODE string.
diff --git a/source/nsswitch/winbindd.c b/source/nsswitch/winbindd.c
index 046ea40f59a..134fdde8882 100644
--- a/source/nsswitch/winbindd.c
+++ b/source/nsswitch/winbindd.c
@@ -1054,7 +1054,8 @@ int main(int argc, char **argv)
init_idmap_child();
- winbindd_flush_nscd_cache();
+ smb_nscd_flush_user_cache();
+ smb_nscd_flush_group_cache();
/* Loop waiting for requests */
diff --git a/source/nsswitch/winbindd_async.c b/source/nsswitch/winbindd_async.c
index 7f282df929d..cde5be8e4c9 100644
--- a/source/nsswitch/winbindd_async.c
+++ b/source/nsswitch/winbindd_async.c
@@ -1469,3 +1469,119 @@ void query_user_async(TALLOC_CTX *mem_ctx, struct winbindd_domain *domain,
do_async_domain(mem_ctx, domain, &request, query_user_recv,
cont, private_data);
}
+
+/* The following uid2sid/gid2sid functions has been contributed by
+ * Keith Reynolds <Keith.Reynolds@centrify.com> */
+
+static void winbindd_uid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const char *sid) = c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger uid2sid\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("uid2sid returned an error\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ cont(private_data, True, response->data.sid.sid);
+}
+
+void winbindd_uid2sid_async(TALLOC_CTX *mem_ctx, uid_t uid,
+ void (*cont)(void *private_data, BOOL success, const char *sid),
+ void *private_data)
+{
+ struct winbindd_request request;
+
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_UID2SID;
+ request.data.uid = uid;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_uid2sid_recv, cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_uid2sid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3,("[%5lu]: uid to sid %lu\n",
+ (unsigned long)state->pid,
+ (unsigned long) state->request.data.uid));
+
+ /* Find sid for this uid and return it, possibly ask the slow remote idmap */
+ result = idmap_uid_to_sid(&sid, state->request.data.uid, ID_EMPTY);
+
+ if (NT_STATUS_IS_OK(result)) {
+ sid_to_string(state->response.data.sid.sid, &sid);
+ state->response.data.sid.type = SID_NAME_USER;
+ return WINBINDD_OK;
+ }
+
+ return WINBINDD_ERROR;
+}
+
+static void winbindd_gid2sid_recv(TALLOC_CTX *mem_ctx, BOOL success,
+ struct winbindd_response *response,
+ void *c, void *private_data)
+{
+ void (*cont)(void *priv, BOOL succ, const char *sid) = c;
+
+ if (!success) {
+ DEBUG(5, ("Could not trigger gid2sid\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ if (response->result != WINBINDD_OK) {
+ DEBUG(5, ("gid2sid returned an error\n"));
+ cont(private_data, False, NULL);
+ return;
+ }
+
+ cont(private_data, True, response->data.sid.sid);
+}
+
+void winbindd_gid2sid_async(TALLOC_CTX *mem_ctx, gid_t gid,
+ void (*cont)(void *private_data, BOOL success, const char *sid),
+ void *private_data)
+{
+ struct winbindd_request request;
+
+ ZERO_STRUCT(request);
+ request.cmd = WINBINDD_DUAL_GID2SID;
+ request.data.gid = gid;
+ do_async(mem_ctx, idmap_child(), &request, winbindd_gid2sid_recv, cont, private_data);
+}
+
+enum winbindd_result winbindd_dual_gid2sid(struct winbindd_domain *domain,
+ struct winbindd_cli_state *state)
+{
+ DOM_SID sid;
+ NTSTATUS result;
+
+ DEBUG(3,("[%5lu]: gid %lu to sid\n",
+ (unsigned long)state->pid,
+ (unsigned long) state->request.data.gid));
+
+ /* Find sid for this gid and return it, possibly ask the slow remote idmap */
+ result = idmap_gid_to_sid(&sid, state->request.data.gid, ID_EMPTY);
+
+ if (NT_STATUS_IS_OK(result)) {
+ sid_to_string(state->response.data.sid.sid, &sid);
+ DEBUG(10, ("[%5lu]: retrieved sid: %s\n",
+ (unsigned long)state->pid,
+ state->response.data.sid.sid));
+ state->response.data.sid.type = SID_NAME_DOM_GRP;
+ return WINBINDD_OK;
+ }
+
+ return WINBINDD_ERROR;
+}
diff --git a/source/nsswitch/winbindd_cache.c b/source/nsswitch/winbindd_cache.c
index 269625ea88b..ce7a6655985 100644
--- a/source/nsswitch/winbindd_cache.c
+++ b/source/nsswitch/winbindd_cache.c
@@ -444,6 +444,7 @@ static void refresh_sequence_number(struct winbindd_domain *domain, BOOL force)
status = domain->backend->sequence_number(domain, &domain->sequence_number);
if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10,("refresh_sequence_number: failed with %s\n", nt_errstr(status)));
domain->sequence_number = DOM_SEQUENCE_NONE;
}
@@ -770,6 +771,10 @@ static void wcache_save_sid_to_name(struct winbindd_domain *domain, NTSTATUS sta
struct cache_entry *centry;
fstring sid_string;
+ if (is_null_sid(sid)) {
+ return;
+ }
+
centry = centry_start(domain, status);
if (!centry)
return;
@@ -789,6 +794,10 @@ static void wcache_save_user(struct winbindd_domain *domain, NTSTATUS status, WI
struct cache_entry *centry;
fstring sid_string;
+ if (is_null_sid(&info->user_sid)) {
+ return;
+ }
+
centry = centry_start(domain, status);
if (!centry)
return;
diff --git a/source/nsswitch/winbindd_dual.c b/source/nsswitch/winbindd_dual.c
index 0cc35277b05..6206bb256f0 100644
--- a/source/nsswitch/winbindd_dual.c
+++ b/source/nsswitch/winbindd_dual.c
@@ -46,7 +46,7 @@ static void child_read_request(struct winbindd_cli_state *state)
sizeof(state->request));
if (len != sizeof(state->request)) {
- DEBUG(0, ("Got invalid request length: %d\n", (int)len));
+ DEBUG(len > 0 ? 0 : 3, ("Got invalid request length: %d\n", (int)len));
state->finished = True;
return;
}
@@ -355,6 +355,8 @@ static struct winbindd_child_dispatch_table child_dispatch_table[] = {
{ WINBINDD_CHECK_MACHACC, winbindd_dual_check_machine_acct, "CHECK_MACHACC" },
{ WINBINDD_DUAL_SID2UID, winbindd_dual_sid2uid, "DUAL_SID2UID" },
{ WINBINDD_DUAL_SID2GID, winbindd_dual_sid2gid, "DUAL_SID2GID" },
+ { WINBINDD_DUAL_UID2SID, winbindd_dual_uid2sid, "DUAL_UID2SID" },
+ { WINBINDD_DUAL_GID2SID, winbindd_dual_gid2sid, "DUAL_GID2SID" },
{ WINBINDD_DUAL_UID2NAME, winbindd_dual_uid2name, "DUAL_UID2NAME" },
{ WINBINDD_DUAL_NAME2UID, winbindd_dual_name2uid, "DUAL_NAME2UID" },
{ WINBINDD_DUAL_GID2NAME, winbindd_dual_gid2name, "DUAL_GID2NAME" },
@@ -590,7 +592,8 @@ static void child_msg_online(int msg_type, struct process_id src, void *buf, siz
/* Set our global state as online. */
set_global_winbindd_state_online();
- winbindd_flush_nscd_cache();
+ smb_nscd_flush_user_cache();
+ smb_nscd_flush_group_cache();
/* Mark everything online - delete any negative cache entries
to force an immediate reconnect. */
diff --git a/source/nsswitch/winbindd_group.c b/source/nsswitch/winbindd_group.c
index 5528b6c78e4..b6dffd1098e 100644
--- a/source/nsswitch/winbindd_group.c
+++ b/source/nsswitch/winbindd_group.c
@@ -329,54 +329,16 @@ void winbindd_getgrnam(struct winbindd_cli_state *state)
request_ok(state);
}
-/* Return a group structure from a gid number */
-
-void winbindd_getgrgid(struct winbindd_cli_state *state)
+static void getgrgid_got_sid(struct winbindd_cli_state *state, DOM_SID group_sid)
{
struct winbindd_domain *domain;
- DOM_SID group_sid;
enum SID_NAME_USE name_type;
fstring dom_name;
fstring group_name;
size_t gr_mem_len;
size_t num_gr_mem;
char *gr_mem;
- NTSTATUS status;
-
- DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid,
- (unsigned long)state->request.data.gid));
-
- /* Bug out if the gid isn't in the winbind range */
-
- if ((state->request.data.gid < server_state.gid_low) ||
- (state->request.data.gid > server_state.gid_high)) {
- request_error(state);
- return;
- }
-
- /* Get sid from gid */
-
- status = idmap_gid_to_sid(&group_sid, state->request.data.gid, 0);
- if (NT_STATUS_IS_OK(status)) {
- /* This is a remote one */
- goto got_sid;
- }
- /* Ok, this might be "ours", i.e. an alias */
-
- if (pdb_gid_to_sid(state->request.data.gid, &group_sid) &&
- lookup_sid(state->mem_ctx, &group_sid, NULL, NULL, &name_type) &&
- (name_type == SID_NAME_ALIAS)) {
- /* Hey, got an alias */
- goto got_sid;
- }
-
- DEBUG(1, ("could not convert gid %lu to sid\n",
- (unsigned long)state->request.data.gid));
- request_error(state);
- return;
-
- got_sid:
/* Get name from sid */
if (!winbindd_lookup_name_by_sid(state->mem_ctx, &group_sid, dom_name,
@@ -423,9 +385,73 @@ void winbindd_getgrgid(struct winbindd_cli_state *state)
state->response.length += gr_mem_len;
state->response.extra_data.data = gr_mem;
+
request_ok(state);
}
+static void getgrgid_recv(void *private_data, BOOL success, const char *sid)
+{
+ struct winbindd_cli_state *state = talloc_get_type_abort(private_data, struct winbindd_cli_state);
+ enum SID_NAME_USE name_type;
+ DOM_SID group_sid;
+
+ if (success) {
+ DEBUG(10,("getgrgid_recv: gid %lu has sid %s\n",
+ (unsigned long)(state->request.data.gid), sid));
+
+ string_to_sid(&group_sid, sid);
+ getgrgid_got_sid(state, group_sid);
+ return;
+ }
+
+ /* Ok, this might be "ours", i.e. an alias */
+ if (pdb_gid_to_sid(state->request.data.gid, &group_sid) &&
+ lookup_sid(state->mem_ctx, &group_sid, NULL, NULL, &name_type) &&
+ (name_type == SID_NAME_ALIAS)) {
+ /* Hey, got an alias */
+ DEBUG(10,("getgrgid_recv: we have an alias with gid %lu and sid %s\n",
+ (unsigned long)(state->request.data.gid), sid));
+ getgrgid_got_sid(state, group_sid);
+ return;
+ }
+
+ DEBUG(1, ("could not convert gid %lu to sid\n",
+ (unsigned long)state->request.data.gid));
+ request_error(state);
+}
+
+/* Return a group structure from a gid number */
+void winbindd_getgrgid(struct winbindd_cli_state *state)
+{
+ DOM_SID group_sid;
+ NTSTATUS status;
+
+ DEBUG(3, ("[%5lu]: getgrgid %lu\n", (unsigned long)state->pid,
+ (unsigned long)state->request.data.gid));
+
+ /* Bug out if the gid isn't in the winbind range */
+
+ if ((state->request.data.gid < server_state.gid_low) ||
+ (state->request.data.gid > server_state.gid_high)) {
+ request_error(state);
+ return;
+ }
+
+ /* Get sid from gid */
+
+ status = idmap_gid_to_sid(&group_sid, state->request.data.gid, ID_EMPTY);
+ if (NT_STATUS_IS_OK(status)) {
+ /* This is a remote one */
+ getgrgid_got_sid(state, group_sid);
+ return;
+ }
+
+ DEBUG(10,("winbindd_getgrgid: gid %lu not found in cache, try with the async interface\n",
+ (unsigned long)state->request.data.gid));
+
+ winbindd_gid2sid_async(state->mem_ctx, state->request.data.gid, getgrgid_recv, state);
+}
+
/*
* set/get/endgrent functions
*/
diff --git a/source/nsswitch/winbindd_nss.h b/source/nsswitch/winbindd_nss.h
index 0ecfa6ce283..9b69eb091d2 100644
--- a/source/nsswitch/winbindd_nss.h
+++ b/source/nsswitch/winbindd_nss.h
@@ -138,6 +138,8 @@ enum winbindd_cmd {
* between parent and children */
WINBINDD_DUAL_SID2UID,
WINBINDD_DUAL_SID2GID,
+ WINBINDD_DUAL_UID2SID,
+ WINBINDD_DUAL_GID2SID,
WINBINDD_DUAL_IDMAPSET,
/* Wrapper around possibly blocking unix nss calls */
diff --git a/source/nsswitch/winbindd_pam.c b/source/nsswitch/winbindd_pam.c
index 66b1f620176..bab2b03f66c 100644
--- a/source/nsswitch/winbindd_pam.c
+++ b/source/nsswitch/winbindd_pam.c
@@ -1791,7 +1791,7 @@ void winbindd_pam_logoff(struct winbindd_cli_state *state)
set_auth_errors(&state->response, NT_STATUS_NO_SUCH_USER);
DEBUG(5, ("Pam Logoff for %s returned %s "
"(PAM: %d)\n",
- state->request.data.auth.user,
+ state->request.data.logoff.user,
state->response.data.auth.nt_status_string,
state->response.data.auth.pam_error));
request_error(state);
diff --git a/source/nsswitch/winbindd_sid.c b/source/nsswitch/winbindd_sid.c
index d489e267cb2..a715f82c790 100644
--- a/source/nsswitch/winbindd_sid.c
+++ b/source/nsswitch/winbindd_sid.c
@@ -269,11 +269,12 @@ static void uid2sid_lookupname_recv(void *private_data, BOOL success,
enum SID_NAME_USE type);
static void uid2sid_idmap_set_mapping_recv(void *private_data, BOOL success);
+static void uid2sid_recv(void *private_data, BOOL success, const char *sid);
+
void winbindd_uid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
NTSTATUS status;
- struct uid2sid_state *uid2sid_state;
DEBUG(3, ("[%5lu]: uid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.uid));
@@ -294,6 +295,25 @@ void winbindd_uid_to_sid(struct winbindd_cli_state *state)
return;
}
+ winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, uid2sid_recv, state);
+}
+
+static void uid2sid_recv(void *private_data, BOOL success, const char *sid)
+{
+ struct winbindd_cli_state *state = private_data;
+ struct uid2sid_state *uid2sid_state;
+
+ if (success) {
+ DEBUG(10,("uid2sid: uid %lu has sid %s\n",
+ (unsigned long)(state->request.data.uid), sid));
+ fstrcpy(state->response.data.sid.sid, sid);
+ state->response.data.sid.type = SID_NAME_USER;
+ request_ok(state);
+ return;
+ }
+
+ /* preexisitng mapping not found go on */
+
if (is_in_uid_range(state->request.data.uid)) {
/* This is winbind's, so we should better have succeeded
* above. */
@@ -309,9 +329,6 @@ void winbindd_uid_to_sid(struct winbindd_cli_state *state)
return;
}
- /* The only chance that this is correct is that winbind trusted
- * domains only = yes, and the user exists in nss and the domain. */
-
uid2sid_state = TALLOC_ZERO_P(state->mem_ctx, struct uid2sid_state);
if (uid2sid_state == NULL) {
DEBUG(0, ("talloc failed\n"));
@@ -396,11 +413,12 @@ static void gid2sid_lookupname_recv(void *private_data, BOOL success,
enum SID_NAME_USE type);
static void gid2sid_idmap_set_mapping_recv(void *private_data, BOOL success);
+static void gid2sid_recv(void *private_data, BOOL success, const char *sid);
+
void winbindd_gid_to_sid(struct winbindd_cli_state *state)
{
DOM_SID sid;
NTSTATUS status;
- struct gid2sid_state *gid2sid_state;
DEBUG(3, ("[%5lu]: gid to sid %lu\n", (unsigned long)state->pid,
(unsigned long)state->request.data.gid));
@@ -421,6 +439,25 @@ void winbindd_gid_to_sid(struct winbindd_cli_state *state)
return;
}
+ winbindd_gid2sid_async(state->mem_ctx, state->request.data.gid, gid2sid_recv, state);
+}
+
+static void gid2sid_recv(void *private_data, BOOL success, const char *sid)
+{
+ struct winbindd_cli_state *state = private_data;
+ struct gid2sid_state *gid2sid_state;
+
+ if (success) {
+ DEBUG(10,("gid2sid: gid %lu has sid %s\n",
+ (unsigned long)(state->request.data.gid), sid));
+ fstrcpy(state->response.data.sid.sid, sid);
+ state->response.data.sid.type = SID_NAME_DOM_GRP;
+ request_ok(state);
+ return;
+ }
+
+ /* preexisitng mapping not found go on */
+
if (is_in_gid_range(state->request.data.gid)) {
/* This is winbind's, so we should better have succeeded
* above. */
diff --git a/source/nsswitch/winbindd_user.c b/source/nsswitch/winbindd_user.c
index 07bd2a30bf7..864bc5f0212 100644
--- a/source/nsswitch/winbindd_user.c
+++ b/source/nsswitch/winbindd_user.c
@@ -388,15 +388,32 @@ static void getpwnam_name2sid_recv(void *private_data, BOOL success,
winbindd_getpwsid(state, sid);
}
-/* Return a password structure given a uid number */
+static void getpwuid_recv(void *private_data, BOOL success, const char *sid)
+{
+ struct winbindd_cli_state *state = private_data;
+ DOM_SID user_sid;
+
+ if (!success) {
+ DEBUG(10,("uid2sid_recv: uid [%lu] to sid mapping failed\n.",
+ (unsigned long)(state->request.data.uid)));
+ request_error(state);
+ return;
+ }
+
+ DEBUG(10,("uid2sid_recv: uid %lu has sid %s\n",
+ (unsigned long)(state->request.data.uid), sid));
+ string_to_sid(&user_sid, sid);
+ winbindd_getpwsid(state, &user_sid);
+}
+
+/* Return a password structure given a uid number */
void winbindd_getpwuid(struct winbindd_cli_state *state)
{
DOM_SID user_sid;
NTSTATUS status;
/* Bug out if the uid isn't in the winbind range */
-
if ((state->request.data.uid < server_state.uid_low ) ||
(state->request.data.uid > server_state.uid_high)) {
request_error(state);
@@ -409,14 +426,15 @@ void winbindd_getpwuid(struct winbindd_cli_state *state)
status = idmap_uid_to_sid(&user_sid, state->request.data.uid,
ID_QUERY_ONLY | ID_CACHE_ONLY);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(5, ("Could not find SID for uid %lu\n",
- (unsigned long)state->request.data.uid));
- request_error(state);
+ if (NT_STATUS_IS_OK(status)) {
+ winbindd_getpwsid(state, &user_sid);
return;
}
- winbindd_getpwsid(state, &user_sid);
+ DEBUG(10,("Could not find SID for uid %lu in the cache. Querying idmap backend\n",
+ (unsigned long)state->request.data.uid));
+
+ winbindd_uid2sid_async(state->mem_ctx, state->request.data.uid, getpwuid_recv, state);
}
/*
diff --git a/source/nsswitch/winbindd_util.c b/source/nsswitch/winbindd_util.c
index 7e7ada52d73..5904ad0989a 100644
--- a/source/nsswitch/winbindd_util.c
+++ b/source/nsswitch/winbindd_util.c
@@ -886,7 +886,8 @@ BOOL parse_domain_user_talloc(TALLOC_CTX *mem_ctx, const char *domuser,
Also, if omit DOMAIN if 'winbind trusted domains only = true', as the
username is then unqualified in unix
-
+
+ We always canonicalize as UPPERCASE DOMAIN, lowercase username.
*/
void fill_domain_username(fstring name, const char *domain, const char *user, BOOL can_assume)
{
@@ -896,7 +897,7 @@ void fill_domain_username(fstring name, const char *domain, const char *user, BO
strlower_m(tmp_user);
if (can_assume && assume_domain(domain)) {
- strlcpy(name, user, sizeof(fstring));
+ strlcpy(name, tmp_user, sizeof(fstring));
} else {
slprintf(name, sizeof(fstring) - 1, "%s%c%s",
domain, *lp_winbind_separator(),
@@ -1217,27 +1218,6 @@ BOOL winbindd_upgrade_idmap(void)
return idmap_convert(idmap_name);
}
-void winbindd_flush_nscd_cache(void)
-{
-#ifdef HAVE_NSCD_FLUSH_CACHE
-
- /* Flush nscd caches to get accurate new information */
- int ret = nscd_flush_cache("passwd");
- if (ret) {
- DEBUG(5,("failed to flush nscd cache for 'passwd' service: %s\n",
- strerror(errno)));
- }
-
- ret = nscd_flush_cache("group");
- if (ret) {
- DEBUG(5,("failed to flush nscd cache for 'group' service: %s\n",
- strerror(errno)));
- }
-#else
- return;
-#endif
-}
-
NTSTATUS lookup_usergroups_cached(struct winbindd_domain *domain,
TALLOC_CTX *mem_ctx,
const DOM_SID *user_sid,
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index dca7f47d8b5..6f0140386a2 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -421,10 +421,10 @@ static BOOL lookup_rids(TALLOC_CTX *mem_ctx, const DOM_SID *domain_sid,
return False;
}
- become_root();
+ become_root_uid_only();
result = pdb_lookup_rids(domain_sid, num_rids, rids,
*names, *types);
- unbecome_root();
+ unbecome_root_uid_only();
return (NT_STATUS_IS_OK(result) ||
NT_STATUS_EQUAL(result, NT_STATUS_NONE_MAPPED) ||
@@ -1069,6 +1069,7 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
{
uid_t low, high;
uint32 rid;
+ BOOL ret;
ZERO_STRUCTP(psid);
@@ -1083,7 +1084,11 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
goto done;
}
- if (pdb_uid_to_rid(uid, &rid)) {
+ become_root_uid_only();
+ ret = pdb_uid_to_rid(uid, &rid);
+ unbecome_root_uid_only();
+
+ if (ret) {
/* This is a mapped user */
sid_copy(psid, get_global_sam_sid());
sid_append_rid(psid, rid);
@@ -1108,6 +1113,7 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
void gid_to_sid(DOM_SID *psid, gid_t gid)
{
+ BOOL ret;
gid_t low, high;
ZERO_STRUCTP(psid);
@@ -1123,7 +1129,11 @@ void gid_to_sid(DOM_SID *psid, gid_t gid)
goto done;
}
- if (pdb_gid_to_sid(gid, psid)) {
+ become_root_uid_only();
+ ret = pdb_gid_to_sid(gid, psid);
+ unbecome_root_uid_only();
+
+ if (ret) {
/* This is a mapped group */
goto done;
}
@@ -1165,8 +1175,13 @@ BOOL sid_to_uid(const DOM_SID *psid, uid_t *puid)
if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
union unid_t id;
+ BOOL ret;
+
+ become_root_uid_only();
+ ret = pdb_sid_to_id(psid, &id, &type);
+ unbecome_root_uid_only();
- if (pdb_sid_to_id(psid, &id, &type)) {
+ if (ret) {
if (type != SID_NAME_USER) {
DEBUG(5, ("sid %s is a %s, expected a user\n",
sid_string_static(psid),
@@ -1240,7 +1255,13 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
if ((sid_check_is_in_builtin(psid) ||
sid_check_is_in_wellknown_domain(psid))) {
- if (pdb_getgrsid(&map, *psid)) {
+ BOOL ret;
+
+ become_root_uid_only();
+ ret = pdb_getgrsid(&map, *psid);
+ unbecome_root_uid_only();
+
+ if (ret) {
*pgid = map.gid;
goto done;
}
@@ -1248,7 +1269,13 @@ BOOL sid_to_gid(const DOM_SID *psid, gid_t *pgid)
}
if (sid_peek_check_rid(get_global_sam_sid(), psid, &rid)) {
- if (pdb_sid_to_id(psid, &id, &type)) {
+ BOOL ret;
+
+ become_root_uid_only();
+ ret = pdb_sid_to_id(psid, &id, &type);
+ unbecome_root_uid_only();
+
+ if (ret) {
if ((type != SID_NAME_DOM_GRP) &&
(type != SID_NAME_ALIAS)) {
DEBUG(5, ("sid %s is a %s, expected a group\n",
diff --git a/source/passdb/pdb_get_set.c b/source/passdb/pdb_get_set.c
index 2e69240b1af..5bea6ce0c4a 100644
--- a/source/passdb/pdb_get_set.c
+++ b/source/passdb/pdb_get_set.c
@@ -72,12 +72,32 @@ time_t pdb_get_pass_last_set_time(const struct samu *sampass)
time_t pdb_get_pass_can_change_time(const struct samu *sampass)
{
- return sampass->pass_can_change_time;
+ 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;
}
time_t pdb_get_pass_must_change_time(const struct samu *sampass)
{
- return sampass->pass_must_change_time;
+ 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;
}
uint16 pdb_get_logon_divs(const struct samu *sampass)
@@ -157,7 +177,7 @@ const DOM_SID *pdb_get_group_sid(struct samu *sampass)
if ( sampass->unix_pw ) {
pwd = sampass->unix_pw;
} else {
- pwd = getpwnam_alloc( sampass, pdb_get_username(sampass) );
+ pwd = Get_Pwnam_alloc( sampass, pdb_get_username(sampass) );
}
if ( !pwd ) {
diff --git a/source/passdb/pdb_interface.c b/source/passdb/pdb_interface.c
index bd06745b3d9..03530d34f78 100644
--- a/source/passdb/pdb_interface.c
+++ b/source/passdb/pdb_interface.c
@@ -366,6 +366,9 @@ static NTSTATUS pdb_default_create_user(struct pdb_methods *methods,
add_ret = smbrun(add_script,NULL);
DEBUG(add_ret ? 0 : 3, ("_samr_create_user: Running the command `%s' gave %d\n",
add_script, add_ret));
+ if (add_ret == 0) {
+ smb_nscd_flush_user_cache();
+ }
flush_pwnam_cache();
pwd = Get_Pwnam_alloc(tmp_ctx, name);
@@ -434,6 +437,9 @@ static int smb_delete_user(const char *unix_user)
all_string_sub(del_script, "%u", unix_user, sizeof(del_script));
ret = smbrun(del_script,NULL);
flush_pwnam_cache();
+ if (ret == 0) {
+ smb_nscd_flush_user_cache();
+ }
DEBUG(ret ? 0 : 3,("smb_delete_user: Running the command `%s' gave %d\n",del_script,ret));
return ret;
diff --git a/source/passdb/pdb_ldap.c b/source/passdb/pdb_ldap.c
index 7ae7e78ed98..f6ca6e9eba9 100644
--- a/source/passdb/pdb_ldap.c
+++ b/source/passdb/pdb_ldap.c
@@ -1869,6 +1869,10 @@ static NTSTATUS ldapsam_rename_sam_account(struct pdb_methods *my_methods,
DEBUG(rc ? 0 : 3,("Running the command `%s' gave %d\n",
rename_script, rc));
+ if (rc == 0) {
+ smb_nscd_flush_user_cache();
+ }
+
if (rc)
return NT_STATUS_UNSUCCESSFUL;
diff --git a/source/passdb/pdb_smbpasswd.c b/source/passdb/pdb_smbpasswd.c
index dc26ff5649d..1bc6813603e 100644
--- a/source/passdb/pdb_smbpasswd.c
+++ b/source/passdb/pdb_smbpasswd.c
@@ -1505,6 +1505,10 @@ static NTSTATUS smbpasswd_rename_sam_account (struct pdb_methods *my_methods,
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
+ if (rename_ret == 0) {
+ smb_nscd_flush_user_cache();
+ }
+
if (rename_ret)
goto done;
} else {
diff --git a/source/passdb/pdb_tdb.c b/source/passdb/pdb_tdb.c
index 45fdd12b273..262e68eb007 100644
--- a/source/passdb/pdb_tdb.c
+++ b/source/passdb/pdb_tdb.c
@@ -1450,6 +1450,10 @@ static NTSTATUS tdbsam_rename_sam_account(struct pdb_methods *my_methods,
DEBUG(rename_ret ? 0 : 3,("Running the command `%s' gave %d\n", rename_script, rename_ret));
+ if (rename_ret == 0) {
+ smb_nscd_flush_user_cache();
+ }
+
if (rename_ret) {
goto done;
}
diff --git a/source/rpc_parse/parse_samr.c b/source/rpc_parse/parse_samr.c
index 0bde3da26c8..0503d308a55 100644
--- a/source/rpc_parse/parse_samr.c
+++ b/source/rpc_parse/parse_samr.c
@@ -6208,6 +6208,7 @@ 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);
@@ -6232,12 +6233,16 @@ 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));
- unix_to_nt_time (&pass_must_change_time,pdb_get_pass_must_change_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);
/* 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 2b65eb210fd..4ce027ad70d 100644
--- a/source/rpc_server/srv_samr_util.c
+++ b/source/rpc_server/srv_samr_util.c
@@ -99,14 +99,6 @@ 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);
@@ -115,14 +107,6 @@ 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);
@@ -284,26 +268,16 @@ void copy_id21_to_sam_passwd(struct samu *to, SAM_USER_INFO_21 *from)
}
}
- 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"));
- }
+ /* 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);
}
}
@@ -348,14 +322,6 @@ 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);
@@ -364,14 +330,6 @@ 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)) {
@@ -524,26 +482,16 @@ void copy_id23_to_sam_passwd(struct samu *to, SAM_USER_INFO_23 *from)
}
}
- 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"));
- }
+ /* 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);
}
}
@@ -587,14 +535,6 @@ 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);
@@ -603,14 +543,6 @@ 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/rpc_server/srv_spoolss_nt.c b/source/rpc_server/srv_spoolss_nt.c
index 0cbc3fcf85d..ffe7f39ebe1 100644
--- a/source/rpc_server/srv_spoolss_nt.c
+++ b/source/rpc_server/srv_spoolss_nt.c
@@ -2897,6 +2897,9 @@ static void spoolss_notify_devmode(int snum,
NT_PRINTER_INFO_LEVEL *printer,
TALLOC_CTX *mem_ctx)
{
+ /* for a dummy implementation we have to zero the fields */
+ data->notify_data.data.length = 0;
+ data->notify_data.data.string = NULL;
}
/*******************************************************************
diff --git a/source/smbd/dir.c b/source/smbd/dir.c
index 5ba9e1ed575..8fbb565efe1 100644
--- a/source/smbd/dir.c
+++ b/source/smbd/dir.c
@@ -61,6 +61,7 @@ struct dptr_struct {
uint32 attr;
char *path;
BOOL has_wild; /* Set to true if the wcard entry has MS wildcard characters in it. */
+ BOOL did_stat; /* Optimisation for non-wcard searches. */
};
static struct bitmap *dptr_bmap;
@@ -535,6 +536,11 @@ long dptr_TellDir(struct dptr_struct *dptr)
return TellDir(dptr->dir_hnd);
}
+BOOL dptr_has_wild(struct dptr_struct *dptr)
+{
+ return dptr->has_wild;
+}
+
/****************************************************************************
Return the next visible file name, skipping veto'd and invisible files.
****************************************************************************/
@@ -557,8 +563,6 @@ static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr, long *poffs
const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT_STAT *pst)
{
- pstring pathreal;
-
SET_STAT_INVALID(*pst);
if (dptr->has_wild) {
@@ -571,55 +575,62 @@ const char *dptr_ReadDirName(struct dptr_struct *dptr, long *poffset, SMB_STRUCT
return NULL;
}
- /* We know the stored wcard contains no wildcard characters. See if we can match
- with a stat call. If we can't, then set has_wild to true to
- prevent us from doing this on every call. */
+ if (!dptr->did_stat) {
+ pstring pathreal;
- /* First check if it should be visible. */
- if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) {
- dptr->has_wild = True;
- return dptr_normal_ReadDirName(dptr, poffset, pst);
- }
+ /* We know the stored wcard contains no wildcard characters. See if we can match
+ with a stat call. If we can't, then set did_stat to true to
+ ensure we only do this once and keep searching. */
- if (VALID_STAT(*pst)) {
- /* We need to set the underlying dir_hdn offset to -1 also as
- this function is usually called with the output from TellDir. */
- dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
- return dptr->wcard;
- }
+ dptr->did_stat = True;
- pstrcpy(pathreal,dptr->path);
- pstrcat(pathreal,"/");
- pstrcat(pathreal,dptr->wcard);
+ /* First check if it should be visible. */
+ if (!is_visible_file(dptr->conn, dptr->path, dptr->wcard, pst, True)) {
+ /* This only returns False if the file was found, but
+ is explicitly not visible. Set us to end of directory,
+ but return NULL as we know we can't ever find it. */
+ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
+ return NULL;
+ }
- if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
- /* We need to set the underlying dir_hdn offset to -1 also as
- this function is usually called with the output from TellDir. */
- dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
- return dptr->wcard;
- } else {
- /* If we get any other error than ENOENT or ENOTDIR
- then the file exists we just can't stat it. */
- if (errno != ENOENT && errno != ENOTDIR) {
- /* We need to set the underlying dir_hdn offset to -1 also as
+ if (VALID_STAT(*pst)) {
+ /* We need to set the underlying dir_hnd offset to -1 also as
this function is usually called with the output from TellDir. */
dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
return dptr->wcard;
}
- }
- /* In case sensitive mode we don't search - we know if it doesn't exist
- with a stat we will fail. */
+ pstrcpy(pathreal,dptr->path);
+ pstrcat(pathreal,"/");
+ pstrcat(pathreal,dptr->wcard);
- if (dptr->conn->case_sensitive) {
- /* We need to set the underlying dir_hdn offset to -1 also as
- this function is usually called with the output from TellDir. */
- dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
- return NULL;
- } else {
- dptr->has_wild = True;
- return dptr_normal_ReadDirName(dptr, poffset, pst);
+ if (SMB_VFS_STAT(dptr->conn,pathreal,pst) == 0) {
+ /* We need to set the underlying dir_hnd offset to -1 also as
+ this function is usually called with the output from TellDir. */
+ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
+ return dptr->wcard;
+ } else {
+ /* If we get any other error than ENOENT or ENOTDIR
+ then the file exists we just can't stat it. */
+ if (errno != ENOENT && errno != ENOTDIR) {
+ /* We need to set the underlying dir_hdn offset to -1 also as
+ this function is usually called with the output from TellDir. */
+ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
+ return dptr->wcard;
+ }
+ }
+
+ /* In case sensitive mode we don't search - we know if it doesn't exist
+ with a stat we will fail. */
+
+ if (dptr->conn->case_sensitive) {
+ /* We need to set the underlying dir_hnd offset to -1 also as
+ this function is usually called with the output from TellDir. */
+ dptr->dir_hnd->offset = *poffset = END_OF_DIRECTORY_OFFSET;
+ return NULL;
+ }
}
+ return dptr_normal_ReadDirName(dptr, poffset, pst);
}
/****************************************************************************
diff --git a/source/smbd/sesssetup.c b/source/smbd/sesssetup.c
index dd8d9fc8525..8c8173ef374 100644
--- a/source/smbd/sesssetup.c
+++ b/source/smbd/sesssetup.c
@@ -327,7 +327,7 @@ static int reply_spnego_kerberos(connection_struct *conn,
/* pass the unmapped username here since map_username()
will be called again from inside make_server_info_info3() */
- ret = make_server_info_info3(mem_ctx, user, domain,
+ ret = make_server_info_info3(mem_ctx, client, domain,
&server_info, &logon_info->info3);
if ( !NT_STATUS_IS_OK(ret) ) {
DEBUG(1,("make_server_info_info3 failed: %s!\n",
diff --git a/source/smbd/share_access.c b/source/smbd/share_access.c
index fcd0a036c74..a8a54123318 100644
--- a/source/smbd/share_access.c
+++ b/source/smbd/share_access.c
@@ -214,6 +214,10 @@ BOOL user_ok_token(const char *username, struct nt_user_token *token, int snum)
const char *list[2];
list[0] = lp_username(snum);
list[1] = NULL;
+ if ((list[0] == NULL) || (*list[0] == '\0')) {
+ DEBUG(0, ("'only user = yes' and no 'username ='\n"));
+ return False;
+ }
if (!token_contains_name_in_list(NULL, lp_servicename(snum),
token, list)) {
DEBUG(10, ("%s != 'username'\n", username));
diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c
index 9030737b1b4..391795eacc4 100644
--- a/source/smbd/trans2.c
+++ b/source/smbd/trans2.c
@@ -944,16 +944,16 @@ static int call_trans2open(connection_struct *conn, char *inbuf, char *outbuf, i
Case can be significant or not.
**********************************************************/
-static BOOL exact_match(char *str,char *mask, BOOL case_sig)
+static BOOL exact_match(connection_struct *conn, char *str, char *mask)
{
if (mask[0] == '.' && mask[1] == 0)
return False;
- if (case_sig)
+ if (conn->case_sensitive)
return strcmp(str,mask)==0;
if (StrCaseCmp(str,mask) != 0) {
return False;
}
- if (ms_has_wild(str)) {
+ if (dptr_has_wild(conn->dirptr)) {
return False;
}
return True;
@@ -1114,7 +1114,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstrcpy(fname,dname);
- if(!(got_match = *got_exact_match = exact_match(fname, mask, conn->case_sensitive)))
+ if(!(got_match = *got_exact_match = exact_match(conn, fname, mask)))
got_match = mask_match(fname, mask, conn->case_sensitive);
if(!got_match && check_mangled_names && !mangle_is_8_3(fname, False, SNUM(conn))) {
@@ -1129,7 +1129,7 @@ static BOOL get_lanman2_dir_entry(connection_struct *conn,
pstring newname;
pstrcpy( newname, fname);
mangle_map( newname, True, False, SNUM(conn));
- if(!(got_match = *got_exact_match = exact_match(newname, mask, conn->case_sensitive)))
+ if(!(got_match = *got_exact_match = exact_match(conn, newname, mask)))
got_match = mask_match(newname, mask, conn->case_sensitive);
}
diff --git a/source/utils/net_ads.c b/source/utils/net_ads.c
index f01f7ac33b3..606e45100e8 100644
--- a/source/utils/net_ads.c
+++ b/source/utils/net_ads.c
@@ -1061,7 +1061,7 @@ static ADS_STATUS net_precreate_machine_acct( ADS_STRUCT *ads, const char *ou )
asprintf(&dn, "%s,%s", ou_str, ads->config.bind_path);
free(ou_str);
- rc = ads_search_dn(ads, &res, dn, NULL);
+ rc = ads_search_dn(ads, (void**)&res, dn, NULL);
ads_msgfree(ads, res);
if (ADS_ERR_OK(rc)) {
@@ -1525,8 +1525,11 @@ static int net_ads_printer_publish(int argc, const char **argv)
return -1;
}
- get_remote_printer_publishing_data(pipe_hnd, mem_ctx, &mods,
- printername);
+ if (!W_ERROR_IS_OK(get_remote_printer_publishing_data(pipe_hnd, mem_ctx, &mods,
+ printername))) {
+ ads_destroy(&ads);
+ return -1;
+ }
rc = ads_add_printer_entry(ads, prt_dn, mem_ctx, &mods);
if (!ADS_ERR_OK(rc)) {
diff --git a/source/utils/net_rpc_samsync.c b/source/utils/net_rpc_samsync.c
index 4f99c3035c8..05d2f1f6703 100644
--- a/source/utils/net_rpc_samsync.c
+++ b/source/utils/net_rpc_samsync.c
@@ -539,6 +539,9 @@ static NTSTATUS fetch_account_info(uint32 rid, SAM_ACCOUNT_INFO *delta)
add_ret = smbrun(add_script,NULL);
DEBUG(add_ret ? 0 : 1,("fetch_account: Running the command `%s' "
"gave %d\n", add_script, add_ret));
+ if (add_ret == 0) {
+ smb_nscd_flush_user_cache();
+ }
}
/* try and find the possible unix account again */
diff --git a/source/utils/net_sam.c b/source/utils/net_sam.c
index 654c9ec5b2a..4c1b967d4e4 100644
--- a/source/utils/net_sam.c
+++ b/source/utils/net_sam.c
@@ -206,23 +206,20 @@ static int net_sam_set_pwnoexp(int argc, const char **argv)
}
/*
- * Set a user's time field
+ * Set pass last change time, based on force pass change now
*/
-static int net_sam_set_time(int argc, const char **argv, const char *field,
- BOOL (*fn)(struct samu *, time_t,
- enum pdb_value_state))
+static int net_sam_set_pwdmustchangenow(int argc, const char **argv)
{
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) {
- d_fprintf(stderr, "usage: net sam set %s <user> "
- "[now|YYYY-MM-DD HH:MM]\n", field);
+ if ((argc != 2) || (!strequal(argv[1], "yes") &&
+ !strequal(argv[1], "no"))) {
+ d_fprintf(stderr, "usage: net sam set pwdmustchangenow <user> [yes|no]\n");
return -1;
}
@@ -238,22 +235,6 @@ static int net_sam_set_time(int argc, const char **argv, const char *field,
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;
@@ -264,9 +245,10 @@ static int net_sam_set_time(int argc, const char **argv, const char *field,
return -1;
}
- if (!fn(sam_acct, new_time, PDB_CHANGED)) {
- d_fprintf(stderr, "Internal error\n");
- 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);
}
status = pdb_update_sam_account(sam_acct);
@@ -278,21 +260,11 @@ static int net_sam_set_time(int argc, const char **argv, const char *field,
TALLOC_FREE(sam_acct);
- d_printf("Updated %s for %s\\%s to %s\n", field, dom, name, argv[1]);
+ d_fprintf(stderr, "Updated 'user must change password at next logon' for %s\\%s to %s\n", 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
@@ -376,10 +348,8 @@ 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" },
- { "pwdmustchange", net_sam_set_pwdmustchange,
- "Set a users password must change time" },
- { "pwdcanchange", net_sam_set_pwdcanchange,
- "Set a users password can change time" },
+ { "pwdmustchangenow", net_sam_set_pwdmustchangenow,
+ "Force users password must change at next logon" },
{NULL, NULL}
};
diff --git a/source/utils/net_usershare.c b/source/utils/net_usershare.c
index 7d6f8d56e27..6a306a99830 100644
--- a/source/utils/net_usershare.c
+++ b/source/utils/net_usershare.c
@@ -458,6 +458,63 @@ static int net_usershare_info(int argc, const char **argv)
}
/***************************************************************************
+ Count the current total number of usershares.
+***************************************************************************/
+
+static int count_num_usershares(void)
+{
+ SMB_STRUCT_DIR *dp;
+ SMB_STRUCT_DIRENT *de;
+ pstring basepath;
+ int num_usershares = 0;
+
+ get_basepath(basepath);
+ dp = sys_opendir(basepath);
+ if (!dp) {
+ d_fprintf(stderr, "count_num_usershares: cannot open usershare directory %s. Error %s\n",
+ basepath, strerror(errno) );
+ return -1;
+ }
+
+ while((de = sys_readdir(dp)) != 0) {
+ SMB_STRUCT_STAT sbuf;
+ pstring path;
+ const char *n = de->d_name;
+
+ /* Ignore . and .. */
+ if (*n == '.') {
+ if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
+ continue;
+ }
+ }
+
+ if (!validate_net_name(n, INVALID_SHARENAME_CHARS, strlen(n))) {
+ d_fprintf(stderr, "count_num_usershares: ignoring bad share name %s\n",n);
+ continue;
+ }
+ pstrcpy(path, basepath);
+ pstrcat(path, "/");
+ pstrcat(path, n);
+
+ if (sys_lstat(path, &sbuf) != 0) {
+ d_fprintf(stderr, "count_num_usershares: can't lstat file %s. Error was %s\n",
+ path, strerror(errno) );
+ continue;
+ }
+
+ if (!S_ISREG(sbuf.st_mode)) {
+ d_fprintf(stderr, "count_num_usershares: file %s is not a regular file. Ignoring.\n",
+ path );
+ continue;
+ }
+ num_usershares++;
+ }
+
+ sys_closedir(dp);
+ return num_usershares;
+}
+
+/***************************************************************************
Add a single userlevel share.
***************************************************************************/
@@ -481,6 +538,7 @@ static int net_usershare_add(int argc, const char **argv)
size_t to_write;
uid_t myeuid = geteuid();
BOOL guest_ok = False;
+ int num_usershares;
us_comment = "";
arg_acl = "S-1-1-0:R";
@@ -528,6 +586,16 @@ static int net_usershare_add(int argc, const char **argv)
break;
}
+ /* Ensure we're under the "usershare max shares" number. Advisory only. */
+ num_usershares = count_num_usershares();
+ if (num_usershares > lp_usershare_max_shares()) {
+ d_fprintf(stderr, "net usershare add: too many usershares already defined (%d), "
+ "maximum number allowed is %d.\n",
+ num_usershares, lp_usershare_max_shares() );
+ SAFE_FREE(sharename);
+ return -1;
+ }
+
if (!validate_net_name(sharename, INVALID_SHARENAME_CHARS, strlen(sharename))) {
d_fprintf(stderr, "net usershare add: share name %s contains "
"invalid characters (any of %s)\n",
diff --git a/source/utils/ntlm_auth.c b/source/utils/ntlm_auth.c
index 5695460378f..17f60345171 100644
--- a/source/utils/ntlm_auth.c
+++ b/source/utils/ntlm_auth.c
@@ -1816,6 +1816,33 @@ enum {
}
}
+ if (opt_username) {
+ char *domain = SMB_STRDUP(opt_username);
+ char *p = strchr_m(domain, *lp_winbind_separator());
+ if (p) {
+ opt_username = p+1;
+ *p = '\0';
+ if (opt_domain && !strequal(opt_domain, domain)) {
+ x_fprintf(x_stderr, "Domain specified in username (%s) "
+ "doesn't match specified domain (%s)!\n\n",
+ domain, opt_domain);
+ poptPrintHelp(pc, stderr, 0);
+ exit(1);
+ }
+ opt_domain = domain;
+ } else {
+ SAFE_FREE(domain);
+ }
+ }
+
+ if (opt_domain == NULL || !*opt_domain) {
+ opt_domain = get_winbind_domain();
+ }
+
+ if (opt_workstation == NULL) {
+ opt_workstation = "";
+ }
+
if (helper_protocol) {
int i;
for (i=0; i<NUM_HELPER_MODES; i++) {
@@ -1833,20 +1860,12 @@ enum {
exit(1);
}
- if (!opt_username) {
+ if (!opt_username || !*opt_username) {
x_fprintf(x_stderr, "username must be specified!\n\n");
poptPrintHelp(pc, stderr, 0);
exit(1);
}
- if (opt_domain == NULL) {
- opt_domain = get_winbind_domain();
- }
-
- if (opt_workstation == NULL) {
- opt_workstation = "";
- }
-
if (opt_challenge.length) {
if (!check_auth_crap()) {
exit(1);
diff --git a/source/utils/pdbedit.c b/source/utils/pdbedit.c
index 0a6fb7e8bec..db8661ecad5 100644
--- a/source/utils/pdbedit.c
+++ b/source/utils/pdbedit.c
@@ -419,8 +419,7 @@ 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,
- time_t pwd_can_change, time_t pwd_must_change)
+ const BOOL badpw, const BOOL hours)
{
BOOL updated_autolock = False, updated_badpw = False;
struct samu *sam_pwent=NULL;
@@ -447,14 +446,6 @@ 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"));
}
@@ -778,8 +769,6 @@ 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;
@@ -814,8 +803,6 @@ 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
@@ -878,9 +865,7 @@ 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) +
- (pwd_can_change_time ? BIT_CAN_CHANGE: 0) +
- (pwd_must_change_time ? BIT_MUST_CHANGE: 0);
+ (hours_reset ? BIT_LOGONHOURS : 0);
if (setparms & BIT_BACKEND) {
if (!NT_STATUS_IS_OK(make_pdb_method_name( &bdef, backend ))) {
@@ -1052,67 +1037,9 @@ 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, pwd_can_change,
- pwd_must_change);
-error:
- fprintf (stderr, "Error parsing the time in pwd-%s-change-time!\n", errstr);
- return -1;
+ user_sid, user_domain, badpw_reset, hours_reset);
}
}