diff options
author | Gerald Carter <jerry@samba.org> | 2006-10-01 21:20:14 +0000 |
---|---|---|
committer | Gerald Carter <jerry@samba.org> | 2006-10-01 21:20:14 +0000 |
commit | 6cd6987fc504a8056295113c12f629ad5c4b2868 (patch) | |
tree | 1cb4088f4b88d086f5b0bc84ffa99aa3c537e0b2 /source | |
parent | 2f4cccbf3b63db498bde48679c228747f1838f91 (diff) | |
download | samba-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')
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); } } |