From: Jeremy Allison Date: Fri, 20 Feb 1998 19:48:01 +0000 (+0000) Subject: nmbd_packets.c: nmbd_subnetdb.c: Patch from Andrey Alekseyev to fix the fact that retransmit_or_expire_response_records() wasn't looking at the WINS subnet. server.c: Patch from jkf@soton.ac.uk to add %p (NIS server path) substitution. smbpass.c: Fix to stop parsing failing on non-valid lines. trans2.c: Fix for volume serial number code. util.c: Patch from jkf@soton.ac.uk to add %p (NIS server path) substitution. Fix for warnings under RH5. gcc 2.8. Jeremy. (This used to be commit e58ab3bbe6e939ba678ad5482e58e0191c8dcbcb) --- diff --git a/source3/include/proto.h b/source3/include/proto.h index 97017e77b0b..a5a7ceec691 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -743,6 +743,7 @@ void write_browse_list(time_t t, BOOL force_write); BOOL create_subnets(); BOOL we_are_a_wins_client(); struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec); +struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec); /*The following definitions come from nmbd_winsproxy.c */ @@ -1485,6 +1486,7 @@ void reset_globals_after_fork(); char *client_name(void); char *client_addr(void); char *automount_server(char *user_name); +char *automount_path(char *user_name); void standard_sub_basic(char *str); BOOL same_net(struct in_addr ip1,struct in_addr ip2,struct in_addr mask); int PutUniCode(char *dst,char *src); diff --git a/source3/lib/util.c b/source3/lib/util.c index fa5f6ae4003..365a7651742 100644 --- a/source3/lib/util.c +++ b/source3/lib/util.c @@ -1580,12 +1580,12 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) #else pstring dir2; pstring wd; - pstring basename; + pstring base_name; pstring newname; char *p=NULL; BOOL relative = (*s != '/'); - *dir2 = *wd = *basename = *newname = 0; + *dir2 = *wd = *base_name = *newname = 0; if (widelinks) { @@ -1608,8 +1608,8 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) /* remove any double slashes */ string_sub(s,"//","/"); - pstrcpy(basename,s); - p = strrchr(basename,'/'); + pstrcpy(base_name,s); + p = strrchr(base_name,'/'); if (!p) return(True); @@ -1634,7 +1634,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) } - if (p && (p != basename)) + if (p && (p != base_name)) { *p = 0; if (strcmp(p+1,".")==0) @@ -1643,10 +1643,10 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) *p = '/'; } - if (ChDir(basename) != 0) + if (ChDir(base_name) != 0) { ChDir(wd); - DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,basename)); + DEBUG(3,("couldn't chdir for %s %s basename=%s\n",s,dir,base_name)); return(False); } @@ -1657,7 +1657,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) return(False); } - if (p && (p != basename)) + if (p && (p != base_name)) { strcat(newname,"/"); strcat(newname,p+1); @@ -3713,44 +3713,88 @@ char *client_addr(void) return addr_buf; } +/******************************************************************* + Patch from jkf@soton.ac.uk + Split Luke's automount_server into YP lookup and string splitter + so can easily implement automount_path(). + As we may end up doing both, cache the last YP result. +*******************************************************************/ + +#if (defined(NETGROUP) && defined(AUTOMOUNT)) +static char *automount_lookup(char *user_name) +{ + static fstring last_key = ""; + static pstring last_value = ""; + + int nis_error; /* returned by yp all functions */ + char *nis_result; /* yp_match inits this */ + int nis_result_len; /* and set this */ + char *nis_domain; /* yp_get_default_domain inits this */ + char *nis_map = (char *)lp_nis_home_map_name(); + + if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) + { + DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); + return last_value; + } + + DEBUG(5, ("NIS Domain: %s\n", nis_domain)); + + if (!strcmp(user_name, last_key)) + { + nis_result = last_value; + nis_result_len = strlen(last_value); + nis_error = 0; + } + else + { + if ((nis_error = yp_match(nis_domain, nis_map, + user_name, strlen(user_name), + &nis_result, &nis_result_len)) != 0) + { + DEBUG(3, ("YP Error: \"%s\" while looking up \"%s\" in map \"%s\"\n", + yperr_string(nis_error), user_name, nis_map)); + } + if (!nis_error && nis_result_len >= sizeof(pstring)) + { + nis_result_len = sizeof(pstring)-1; + } + fstrcpy(last_key, user_name); + strncpy(last_value, nis_result, nis_result_len); + last_value[nis_result_len] = '\0'; + } + + DEBUG(4, ("YP Lookup: %s resulted in %s\n", user_name, last_value)); + return last_value; +} +#endif + +/******************************************************************* + Patch from jkf@soton.ac.uk + This is Luke's original function with the NIS lookup code + moved out to a separate function. +*******************************************************************/ + char *automount_server(char *user_name) { static pstring server_name; #if (defined(NETGROUP) && defined (AUTOMOUNT)) - int nis_error; /* returned by yp all functions */ - char *nis_result; /* yp_match inits this */ - int nis_result_len; /* and set this */ - char *nis_domain; /* yp_get_default_domain inits this */ - char *nis_map = (char *)lp_nis_home_map_name(); int home_server_len; /* set to default of local machine */ pstrcpy(server_name, local_machine); - if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) + if (lp_nis_home_map()) { - DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); - } - - DEBUG(5, ("NIS Domain: %s\n", nis_domain)); - - if ((nis_error = yp_match(nis_domain, nis_map, - user_name, strlen(user_name), - &nis_result, &nis_result_len)) != 0) - { - DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); - } - - if (!nis_error && lp_nis_home_map()) - { - home_server_len = strcspn(nis_result,":"); + char *automount_value = automount_lookup(user_name); + home_server_len = strcspn(automount_value,":"); DEBUG(5, ("NIS lookup succeeded. Home server length: %d\n",home_server_len)); if (home_server_len > sizeof(pstring)) { home_server_len = sizeof(pstring); } - strncpy(server_name, nis_result, home_server_len); + strncpy(server_name, automount_value, home_server_len); server_name[home_server_len] = '\0'; } #else @@ -3763,6 +3807,44 @@ char *automount_server(char *user_name) return server_name; } +/******************************************************************* + Patch from jkf@soton.ac.uk + Added this to implement %p (NIS auto-map version of %H) +*******************************************************************/ + +char *automount_path(char *user_name) +{ + static pstring server_path; + +#if (defined(NETGROUP) && defined (AUTOMOUNT)) + char *home_path_start; + + /* set to default of no string */ + server_path[0] = 0; + + if (lp_nis_home_map()) + { + char *automount_value = automount_lookup(user_name); + home_path_start = strchr(automount_value,':'); + if (home_path_start != NULL) + { + DEBUG(5, ("NIS lookup succeeded. Home path is: %s\n", + home_path_start?(home_path_start+1):"")); + strcpy(server_path, home_path_start+1); + } + } +#else + /* use the passwd entry instead of the auto-map server entry */ + /* pstrcpy() copes with get_home_dir() returning NULL */ + pstrcpy(server_path, get_home_dir(user_name)); +#endif + + DEBUG(4,("Home server path: %s\n", server_path)); + + return server_path; +} + + /******************************************************************* sub strings with useful parameters Rewritten by Stefaan A Eeckels and diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index 9dad5ddaa99..cd99343e709 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -1486,14 +1486,18 @@ void run_packet_queue() /******************************************************************* Retransmit or timeout elements from all the outgoing subnet response - record queues. + record queues. NOTE that this code must also check the WINS server + subnet for response records to timeout as the WINS server code + can send requests to check if a client still owns a name. + (Patch from Andrey Alekseyev ). ******************************************************************/ void retransmit_or_expire_response_records(time_t t) { struct subnet_record *subrec; - for (subrec = FIRST_SUBNET; subrec; subrec = NEXT_SUBNET_INCLUDING_UNICAST(subrec)) + for (subrec = FIRST_SUBNET; subrec; + subrec = get_next_subnet_maybe_unicast_or_wins_server(subrec)) { struct response_record *rrec, *nextrrec; diff --git a/source3/nmbd/nmbd_subnetdb.c b/source3/nmbd/nmbd_subnetdb.c index 5e18fe9cc0c..07692cc82c2 100644 --- a/source3/nmbd/nmbd_subnetdb.c +++ b/source3/nmbd/nmbd_subnetdb.c @@ -289,3 +289,27 @@ struct subnet_record *get_next_subnet_maybe_unicast(struct subnet_record *subrec else return subrec->next; } + +/******************************************************************* + Access function used by retransmit_or_expire_response_records() in + nmbd_packets.c. Patch from Andrey Alekseyev + Needed when we need to enumerate all the broadcast, unicast and + WINS subnets. +******************************************************************/ + +struct subnet_record *get_next_subnet_maybe_unicast_or_wins_server(struct subnet_record *subrec) +{ + if(subrec == unicast_subnet) + if(wins_server_subnet) + return wins_server_subnet; + else + return NULL; + + if(wins_server_subnet && subrec == wins_server_subnet) + return NULL; + + if((subrec->next == NULL) && we_are_a_wins_client()) + return unicast_subnet; + else + return subrec->next; +} diff --git a/source3/passdb/smbpass.c b/source3/passdb/smbpass.c index ea386bfa9df..fbda8949bcb 100644 --- a/source3/passdb/smbpass.c +++ b/source3/passdb/smbpass.c @@ -225,9 +225,7 @@ struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid) p++; /* Go past ':' */ if (!isdigit(*p)) { DEBUG(0, ("get_smbpwd_entry: malformed password entry (uid not number)\n")); - fclose(fp); - pw_file_unlock(lockfd); - return NULL; + continue; } uidval = atoi((char *) p); @@ -240,9 +238,7 @@ struct smb_passwd *get_smbpwd_entry(char *name, int smb_userid) if (*p != ':') { DEBUG(0, ("get_smbpwd_entry: malformed password entry (no : after uid)\n")); - fclose(fp); - pw_file_unlock(lockfd); - return NULL; + continue; } if (name != NULL) diff --git a/source3/smbd/server.c b/source3/smbd/server.c index c2880b0e890..9c25a21000f 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -4569,6 +4569,15 @@ void standard_sub(int cnum,char *str) case 'S' : string_sub(p,"%S",lp_servicename(Connections[cnum].service)); break; case 'g' : string_sub(p,"%g",gidtoname(Connections[cnum].gid)); break; case 'u' : string_sub(p,"%u",Connections[cnum].user); break; + /* + * Patch from jkf@soton.ac.uk + * Left the %N (NIS server name) in standard_sub_basic as it + * is a feature for logon servers, hence uses the username. + * The %p (NIS server path) code is here as it is used + * instead of the default "path =" string in [homes] and so + * needs the service name, not the username. + */ + case 'p' : string_sub(p,"%p",automount_path(lp_servicename(Connections[cnum].service))); break; case '\0' : p++; break; /* don't run off the end of the string */ default : p+=2; break; } diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 6eda891e328..893f1adc66b 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -977,7 +977,7 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize * Add volume serial number - hash of a combination of * the called hostname and the service name. */ - SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ str_checksum(local_machine) ); + SIVAL(pdata,0,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) ); SCVAL(pdata,l2_vol_cch,volname_len); StrnCpy(pdata+l2_vol_szVolLabel,vname,volname_len); DEBUG(5,("call_trans2qfsinfo : time = %x, namelen = %d, name = %s\n",st.st_ctime, volname_len, @@ -1002,7 +1002,7 @@ static int call_trans2qfsinfo(char *inbuf, char *outbuf, int length, int bufsize * Add volume serial number - hash of a combination of * the called hostname and the service name. */ - SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ str_checksum(local_machine) ); + SIVAL(pdata,8,str_checksum(lp_servicename(snum)) ^ (str_checksum(local_machine)<<16) ); SIVAL(pdata,12,2*strlen(vname)); PutUniCode(pdata+18,vname); DEBUG(5,("call_trans2qfsinfo : SMB_QUERY_FS_VOLUME_INFO namelen = %d, vol = %s\n", strlen(vname),