From 3e074dcd9664edc32d1d4947179ce90d5c4ae801 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 1997 19:44:48 +0000 Subject: Updated code on 1.9.17 branch to add bug fixes. This is *NOT* the same branch as the main (ie. 1.9.18) branch. Jeremy (jallison@whistle.com) --- source/client/clientutil.c | 6 ++++ source/client/clitar.c | 3 +- source/include/includes.h | 4 +++ source/include/proto.h | 26 ++++++++++------ source/include/smb.h | 2 ++ source/include/version.h | 2 +- source/lib/charset.c | 2 +- source/lib/util.c | 47 ++++++++++++++++++++++++++-- source/nameannounce.c | 2 +- source/namepacket.c | 15 ++++++--- source/nameresp.c | 14 ++++----- source/nameserv.c | 6 ++-- source/nameservreply.c | 78 +++++++++++++++++++++++++++------------------- source/nmbsync.c | 2 ++ source/param/loadparm.c | 19 +++++++++-- source/printing/printing.c | 24 ++++++++++++-- source/script/mkproto.awk | 2 +- source/smbd/ipc.c | 25 +++++++-------- source/smbd/mangle.c | 2 +- source/smbd/password.c | 20 ++++++++++-- source/smbd/reply.c | 41 +++++++++++++++++++++--- source/smbd/server.c | 68 +++++++++++++++++++++++++++++++--------- source/smbd/trans2.c | 10 ++---- 23 files changed, 308 insertions(+), 112 deletions(-) diff --git a/source/client/clientutil.c b/source/client/clientutil.c index 000cbba1a78..b4f0849c5fe 100644 --- a/source/client/clientutil.c +++ b/source/client/clientutil.c @@ -428,6 +428,12 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu else pass = (char *)getpass("Password: "); + if(pass == NULL) + { + DEBUG(0, ("cli_send_login : no password available - logon failed.\n")); + return False; + } + if (Protocol >= PROTOCOL_LANMAN1 && use_setup) { fstring pword; diff --git a/source/client/clitar.c b/source/client/clitar.c index f70e639e905..d5bca8c5bbb 100644 --- a/source/client/clitar.c +++ b/source/client/clitar.c @@ -376,8 +376,7 @@ Compare two strings in a slash insensitive way, allowing s1 to match s2 if s1 is an "initial" string (up to directory marker). Thus, if s2 is a file in any subdirectory of s1, declare a match. ***************************************************************************/ -static -int strslashcmp(char *s1, char *s2) +static int strslashcmp(char *s1, char *s2) { char *s1_0=s1; diff --git a/source/include/includes.h b/source/include/includes.h index 15a5e74e469..a63f8f8597c 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -308,7 +308,9 @@ extern int innetgr (const char *, const char *, const char *, const char *); #define USE_STATVFS #define USE_GETCWD #define USE_SETSID +#ifndef REPLACE_GETPASS #define REPLACE_GETPASS +#endif /* REPLACE_GETPASS */ #define USE_SIGPROCMASK #endif @@ -459,7 +461,9 @@ char *mktemp(char *); /* No standard include */ #define NO_FSYNC #define USE_GETCWD #define USE_SETSID +#ifndef REPLACE_GETPASS #define REPLACE_GETPASS +#endif /* REPLACE_GETPASS */ #define NO_GETRLIMIT #endif /* CLIX */ diff --git a/source/include/proto.h b/source/include/proto.h index 9f05e5bbffd..01afb7cad95 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -146,6 +146,7 @@ char *lp_wins_server(void); char *lp_interfaces(void); char *lp_socket_address(void); char *lp_nis_home_map_name(void); +char *lp_announce_version(void); char *lp_netbios_aliases(void); BOOL lp_dns_proxy(void); BOOL lp_wins_support(void); @@ -189,6 +190,7 @@ int lp_maxdisksize(void); int lp_lpqcachetime(void); int lp_syslog(void); int lp_client_code_page(void); +int lp_announce_as(void); char *lp_preexec(int ); char *lp_postexec(int ); char *lp_rootpreexec(int ); @@ -268,10 +270,10 @@ BOOL lp_load(char *pszFname,BOOL global_only); int lp_numservices(void); void lp_dump(void); int lp_servicenumber(char *pszServiceName); +char *volume_label(int snum); int lp_default_server_announce(void); int lp_major_announce_version(void); int lp_minor_announce_version(void); -char *volume_label(int snum); /*The following definitions come from locking.c */ @@ -460,7 +462,9 @@ void initiate_netbios_packet(uint16 *id, int nb_flags,BOOL bcast,BOOL recurse, struct in_addr to_ip); void reply_netbios_packet(struct packet_struct *p1,int trn_id, - int rcode, int rcv_code, int opcode, BOOL recurse, + int rcode, int rcv_code, int opcode, + BOOL recursion_available, + BOOL recursion_desired, struct nmb_name *rr_name,int rr_type,int rr_class,int ttl, char *data,int len); void queue_packet(struct packet_struct *packet); @@ -486,7 +490,6 @@ struct response_record *queue_netbios_pkt_wins( int fd,int quest_type,enum state_type state, char *name,int name_type,int nb_flags, time_t ttl, int server_type, char *my_name, char *my_comment, - BOOL bcast,BOOL recurse, struct in_addr send_ip, struct in_addr reply_to_ip); struct response_record *queue_netbios_packet(struct subnet_record *d, int fd,int quest_type,enum state_type state,char *name, @@ -613,9 +616,12 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, print_status_struct *status); void del_printqueue(int cnum,int snum,int jobid); void status_printjob(int cnum,int snum,int jobid,int status); +int printjob_encode(int snum, int job); +void printjob_decode(int jobid, int *snum, int *job); /*The following definitions come from quotas.c */ +BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize); @@ -726,22 +732,22 @@ void close_cnum(int cnum, uint16 vuid); BOOL yield_connection(int cnum,char *name,int max_connections); BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear); void exit_server(char *reason); -void standard_sub(int cnum,char *string); +void standard_sub(int cnum,char *str); char *smb_fn_name(int type); int chain_reply(char *inbuf,char *outbuf,int size,int bufsize); int construct_reply(char *inbuf,char *outbuf,int size,int bufsize); /*The following definitions come from shmem.c */ -smb_shm_offset_t smb_shm_alloc(int size); -smb_shm_offset_t smb_shm_addr2offset(void *addr); -smb_shm_offset_t smb_shm_get_userdef_off(void); BOOL smb_shm_create_hash_table( unsigned int size ); BOOL smb_shm_open( char *file_name, int size); BOOL smb_shm_close( void ); +smb_shm_offset_t smb_shm_alloc(int size); BOOL smb_shm_free(smb_shm_offset_t offset); +smb_shm_offset_t smb_shm_get_userdef_off(void); BOOL smb_shm_set_userdef_off(smb_shm_offset_t userdef_off); void * smb_shm_offset2addr(smb_shm_offset_t offset); +smb_shm_offset_t smb_shm_addr2offset(void *addr); BOOL smb_shm_lock_hash_entry( unsigned int entry); BOOL smb_shm_unlock_hash_entry( unsigned int entry ); BOOL smb_shm_get_usage(int *bytes_free, @@ -873,7 +879,7 @@ uint32 file_size(char *file_name); char *attrib_string(int mode); int StrCaseCmp(const char *s, const char *t); int StrnCaseCmp(const char *s, const char *t, int n); -BOOL strequal(const char *s1,const char *s2); +BOOL strequal(const char *s1, const char *s2); BOOL strnequal(const char *s1,const char *s2,int n); BOOL strcsequal(char *s1,char *s2); void strlower(char *s); @@ -951,7 +957,7 @@ BOOL zero_ip(struct in_addr ip); void reset_globals_after_fork(); char *client_name(void); char *client_addr(void); -void standard_sub_basic(char *string); +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); struct hostent *Get_Hostbyname(char *name); @@ -968,6 +974,8 @@ BOOL fcntl_lock(int fd,int op,uint32 offset,uint32 count,int type); int file_lock(char *name,int timeout); void file_unlock(int fd); BOOL is_myname(const char *s); +void set_remote_arch(enum remote_arch_types type); +enum remote_arch_types get_remote_arch(); /*The following definitions come from vt_mode.c */ diff --git a/source/include/smb.h b/source/include/smb.h index f0390230e53..b55c180f361 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -880,6 +880,8 @@ enum security_types {SEC_SHARE,SEC_USER,SEC_SERVER}; enum printing_types {PRINT_BSD,PRINT_SYSV,PRINT_AIX,PRINT_HPUX, PRINT_QNX,PRINT_PLP,PRINT_LPRNG}; +/* Remote architectures we know about. */ +enum remote_arch_types {RA_UNKNOWN, RA_WFWG, RA_OS2, RA_WIN95, RA_WINNT, RA_SAMBA}; /* case handling */ enum case_handling {CASE_LOWER,CASE_UPPER}; diff --git a/source/include/version.h b/source/include/version.h index 56ee92c13f3..afd20f5799d 100644 --- a/source/include/version.h +++ b/source/include/version.h @@ -1 +1 @@ -#define VERSION "1.9.17" +#define VERSION "1.9.17p1" diff --git a/source/lib/charset.c b/source/lib/charset.c index 0bbf99e29f5..c4f67e75fb1 100644 --- a/source/lib/charset.c +++ b/source/lib/charset.c @@ -280,7 +280,7 @@ void codepage_initialise(int client_codepage) if(cp) { - for(i = 0; (cp[i][0] != '\0') && (cp[i][1] != '\0'); i++) + for(i = 0; !((cp[i][0] == '\0') && (cp[i][1] == '\0')); i++) add_dos_char(cp[i][0], (BOOL)cp[i][2], cp[i][1], (BOOL)cp[i][3]); } diff --git a/source/lib/util.c b/source/lib/util.c index d78ecf2728a..7f922def7e3 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -68,6 +68,7 @@ BOOL case_mangle; fstring remote_machine=""; fstring local_machine=""; fstring remote_arch="UNKNOWN"; +static enum remote_arch_types ra_type = RA_UNKNOWN; fstring remote_proto="UNKNOWN"; pstring myhostname=""; pstring user_socket_options=""; @@ -91,7 +92,11 @@ void setup_logging(char *pname,BOOL interactive) if (!interactive) { char *p = strrchr(pname,'/'); if (p) pname = p+1; +#ifdef LOG_DAEMON openlog(pname, LOG_PID, LOG_DAEMON); +#else /* LOG_DAEMON - for old systems that have no facility codes. */ + openlog(pname, LOG_PID); +#endif /* LOG_DAEMON */ } #endif if (interactive) { @@ -3301,13 +3306,13 @@ sub strings with useful parameters Rewritten by Stefaan A Eeckels and Paul Rippin ********************************************************************/ -void standard_sub_basic(char *string) +void standard_sub_basic(char *str) { char *s, *p; char pidstr[10]; struct passwd *pass; - for (s = string ; (p = strchr(s,'%')) != NULL ; s = p ) + for (s = str ; (p = strchr(s,'%')) != NULL ; s = p ) { switch (*(p+1)) { @@ -3864,3 +3869,41 @@ BOOL is_myname(const char *s) DEBUG(8, ("is_myname(\"%s\") returns %d\n", s, ret)); return(ret); } + +/******************************************************************* +set the horrid remote_arch string based on an enum. +********************************************************************/ +void set_remote_arch(enum remote_arch_types type) +{ + ra_type = type; + switch( type ) + { + case RA_WFWG: + strcpy(remote_arch, "WfWg"); + return; + case RA_OS2: + strcpy(remote_arch, "OS2"); + return; + case RA_WIN95: + strcpy(remote_arch, "Win95"); + return; + case RA_WINNT: + strcpy(remote_arch, "WinNT"); + return; + case RA_SAMBA: + strcpy(remote_arch,"Samba"); + return; + default: + ra_type = RA_UNKNOWN; + strcpy(remote_arch, "UNKNOWN"); + break; + } +} + +/******************************************************************* + Get the remote_arch type. +********************************************************************/ +enum remote_arch_types get_remote_arch() +{ + return ra_type; +} diff --git a/source/nameannounce.c b/source/nameannounce.c index 2f169e9287c..684ef412581 100644 --- a/source/nameannounce.c +++ b/source/nameannounce.c @@ -430,7 +430,7 @@ workgroup %s\n", am_master, work->work_group)); NMB_QUERY,NAME_QUERY_DOM_SRV_CHK, name, type, 0,0,0, work->work_group,NULL, - False, True, ipzero, ipzero); + ipzero, ipzero); } else if(lp_wins_support()) { diff --git a/source/namepacket.c b/source/namepacket.c index 086e32d9081..d60ef9f6ae2 100644 --- a/source/namepacket.c +++ b/source/namepacket.c @@ -183,10 +183,12 @@ void initiate_netbios_packet(uint16 *id, /**************************************************************************** - reply to a netbios name packet + reply to a netbios name packet. see rfc1002.txt ****************************************************************************/ void reply_netbios_packet(struct packet_struct *p1,int trn_id, - int rcode, int rcv_code, int opcode, BOOL recurse, + int rcode, int rcv_code, int opcode, + BOOL recursion_available, + BOOL recursion_desired, struct nmb_name *rr_name,int rr_type,int rr_class,int ttl, char *data,int len) { @@ -197,6 +199,11 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id, p = *p1; + if (recursion_available && lp_wins_server()) + { + DEBUG(0,("reply_netbios_packet: r_a not to be used when not a WINS server\n")); + } + switch (rcv_code) { case NMB_STATUS: @@ -240,8 +247,8 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id, nmb->header.opcode = opcode; nmb->header.response = True; nmb->header.nm_flags.bcast = False; - nmb->header.nm_flags.recursion_available = (lp_wins_support() ? True : False ); - nmb->header.nm_flags.recursion_desired = (lp_wins_support() ? recurse : False ); + nmb->header.nm_flags.recursion_available = recursion_available; + nmb->header.nm_flags.recursion_desired = recursion_desired; nmb->header.nm_flags.trunc = False; nmb->header.nm_flags.authoritative = True; diff --git a/source/nameresp.c b/source/nameresp.c index 23e70a7064d..f44171f4b67 100644 --- a/source/nameresp.c +++ b/source/nameresp.c @@ -117,7 +117,7 @@ static void dead_netbios_entry(struct subnet_record *d, add_name_respond(d,n->fd,d->myip, n->response_id ,&n->name, n->nb_flags, GET_TTL(0), - n->reply_to_ip, False, n->reply_to_ip); + n->reply_to_ip, True, n->reply_to_ip); if (!n->bcast && n->num_msgs == 0) { @@ -250,7 +250,6 @@ struct response_record *queue_netbios_pkt_wins( int fd,int quest_type,enum state_type state, char *name,int name_type,int nb_flags, time_t ttl, int server_type, char *my_name, char *my_comment, - BOOL bcast,BOOL recurse, struct in_addr send_ip, struct in_addr reply_to_ip) { /* XXXX note: please see rfc1001.txt section 10 for details on this @@ -260,30 +259,29 @@ struct response_record *queue_netbios_pkt_wins( */ if ((!lp_wins_support()) && (*lp_wins_server())) - { + { /* samba is not a WINS server, and we are using a WINS server */ struct in_addr real_wins_ip; real_wins_ip = *interpret_addr2(lp_wins_server()); - if (!zero_ip(real_wins_ip)) + if (!zero_ip(real_wins_ip)) { - bcast = False; send_ip = real_wins_ip; } - else + else { /* oops. smb.conf's wins server parameter MUST be a host_name or an ip_address. */ DEBUG(0,("invalid smb.conf parameter 'wins server'\n")); } - } + } if (zero_ip(send_ip)) return NULL; return queue_netbios_packet(wins_subnet,fd, quest_type, state, name, name_type, nb_flags, ttl, server_type,my_name,my_comment, - bcast, recurse, send_ip, reply_to_ip); + False, True, send_ip, reply_to_ip); } diff --git a/source/nameserv.c b/source/nameserv.c index 96bb1c0eac8..ccd0ef379cb 100644 --- a/source/nameserv.c +++ b/source/nameserv.c @@ -103,7 +103,7 @@ void remove_name_entry(struct subnet_record *d, char *name,int type) /* not a WINS server: we have to release them on the network */ queue_netbios_pkt_wins(ClientNMB,NMB_REL,NAME_RELEASE, name, type, 0, 0,0,NULL,NULL, - False, True, ipzero, ipzero); + ipzero, ipzero); } } else @@ -163,7 +163,7 @@ void add_my_name_entry(struct subnet_record *d,char *name,int type,int nb_flags) queue_netbios_pkt_wins(ClientNMB, re_reg ? NMB_REG_REFRESH : NMB_REG, NAME_REGISTER, name, type, nb_flags, GET_TTL(0),0,NULL,NULL, - False, True, ipzero, ipzero); + ipzero, ipzero); } } else @@ -308,7 +308,7 @@ for domain master on workgroup %s\n", myworkgroup)); NAME_QUERY_DOMAIN, myworkgroup, 0x1b, 0, 0,0,NULL,NULL, - False, True, ipzero, ipzero); + ipzero, ipzero); } } } diff --git a/source/nameservreply.c b/source/nameservreply.c index e5976bb7429..5b9c476549d 100644 --- a/source/nameservreply.c +++ b/source/nameservreply.c @@ -42,7 +42,8 @@ extern struct in_addr wins_ip; send a registration / release response: pos/neg **************************************************************************/ static void send_name_response(int fd, struct in_addr from_ip, - int name_trn_id, int opcode, BOOL success, BOOL recurse, + int name_trn_id, int opcode, BOOL success, + BOOL recursion_available, BOOL recursion_desired, struct nmb_name *reply_name, int nb_flags, int ttl, struct in_addr ip) { @@ -56,7 +57,7 @@ static void send_name_response(int fd, struct in_addr from_ip, /* NEGATIVE RESPONSE */ rcode = 6; } - else if (opcode == NMB_REG && recurse == False) + else if (opcode == NMB_REG && !recursion_available) { /* END-NODE CHALLENGE REGISTRATION RESPONSE */ rcode = 0; @@ -73,7 +74,8 @@ static void send_name_response(int fd, struct in_addr from_ip, p.packet_type = NMB_PACKET; reply_netbios_packet(&p,name_trn_id, - rcode,opcode,opcode,recurse, + rcode,opcode,opcode, + recursion_available, recursion_desired, reply_name, 0x20, 0x1, ttl, rdata, 6); @@ -93,8 +95,10 @@ void add_name_respond(struct subnet_record *d, int fd, struct in_addr from_ip, nb_flags,ttl,REGISTER,register_ip,False,True); /* reply yes or no to the host that requested the name */ + /* see rfc1002.txt - 4.2.10 and 4.2.11 */ send_name_response(fd,from_ip, response_id, NMB_REG, - new_owner, False, + new_owner, + True, True, name, nb_flags, ttl, reply_to_ip); } @@ -160,7 +164,7 @@ subnet %s\n", namestr(&nmb->question.question_name), n->name.name_type, /* Send a NAME RELEASE RESPONSE (pos/neg) see rfc1002.txt 4.2.10-11 */ send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REL, - success, nmb->header.nm_flags.recursion_desired, + success, False, False, &nmb->question.question_name, nb_flags, 0, ip); } @@ -301,26 +305,29 @@ void reply_name_reg(struct packet_struct *p) /* send WAIT ACKNOWLEDGEMENT see rfc1002.txt 4.2.16 */ reply_netbios_packet(p,nmb->header.name_trn_id, - 0,NMB_WAIT_ACK,NMB_WAIT_ACK,False, + 0,NMB_WAIT_ACK,NMB_WAIT_ACK, + False,False, reply_name, 0x0a, 0x01, 15*1000, /* 15 seconds long enough to wait? */ rdata, 2); /* initiate some enquiries to the current owner. */ queue_netbios_packet(d,ClientNMB,NMB_QUERY, - NAME_REGISTER_CHALLENGE, - reply_name->name,reply_name->name_type, - nb_flags,0,0,NULL,NULL, - False, False, n->ip_flgs[0].ip, p->ip); + NAME_REGISTER_CHALLENGE, + reply_name->name,reply_name->name_type, + nb_flags,0,0,NULL,NULL, + False, False, + n->ip_flgs[0].ip, p->ip); } else { - /* Send a NAME REGISTRATION RESPONSE (pos/neg) see rfc1002.txt 4.2.13-14 + /* Send a NAME REGISTRATION RESPONSE (pos/neg) see rfc1002.txt 4.2.5-6 or an END-NODE CHALLENGE REGISTRATION RESPONSE see rfc1002.txt 4.2.7 */ send_name_response(p->fd,p->ip, nmb->header.name_trn_id, NMB_REG, - success, nmb->header.nm_flags.recursion_desired, + success, + True, True, reply_name, nb_flags, ttl, ip); } } @@ -471,7 +478,7 @@ void reply_name_status(struct packet_struct *p) /* Send a POSITIVE NAME STATUS RESPONSE */ reply_netbios_packet(p,nmb->header.name_trn_id, - 0,NMB_STATUS,0,True, + 0,NMB_STATUS,0,False, False, &nmb->question.question_name, 0x21, 0x01, 0, rdata,PTR_DIFF(buf,rdata)); @@ -507,7 +514,10 @@ void reply_name_query(struct packet_struct *p) struct nmb_packet *nmb = &p->packet.nmb; struct nmb_name *question = &nmb->question.question_name; int name_type = question->name_type; + BOOL bcast = nmb->header.nm_flags.bcast; + BOOL query_is_to_wins_server = (!bcast && + nmb->header.nm_flags.recursion_desired); int ttl=0; int rcode = 0; int nb_flags = 0; @@ -516,26 +526,31 @@ void reply_name_query(struct packet_struct *p) struct subnet_record *d = NULL; BOOL success = True; struct name_record *n = NULL; + BOOL acting_as_wins_server = lp_wins_support(); /* directed queries are for WINS server: broadcasts are local SELF queries. the exception is Domain Master names. */ - int search = bcast ? FIND_LOCAL | FIND_WINS: FIND_WINS; - - if (search & FIND_LOCAL) + if (query_is_to_wins_server) { - if (!(d = find_req_subnet(p->ip, bcast))) + /* queries to the WINS server involve the WINS server subnet */ + if (!(d = wins_subnet)) { - DEBUG(3,("name query: bcast %s not known\n", + DEBUG(3,("name query: wins search %s not known\n", inet_ntoa(p->ip))); success = False; } } else { - if (!(d = wins_subnet)) + /* queries to the WINS client involve, unfortunately, the WINS subnet + because it contains WINS client (SELF) entries, as _well_ as WINS + server entries. not good. + */ + + if (!(d = find_subnet(*iface_bcast(p->ip)))) { - DEBUG(3,("name query: wins search %s not known\n", + DEBUG(3,("name query: interface for %s not known\n", inet_ntoa(p->ip))); success = False; } @@ -544,12 +559,6 @@ void reply_name_query(struct packet_struct *p) DEBUG(3,("Name query from %s for name %s<0x%x>\n", inet_ntoa(p->ip), question->name, question->name_type)); - if (search == 0) - { - /* eh? no criterion for searching database. help! */ - success = False; - } - if (!bcast && (name_type == 0x1d) && lp_wins_support()) { /* see WINS manager HELP - 'How WINS Handles Special Names' */ @@ -560,7 +569,7 @@ void reply_name_query(struct packet_struct *p) if (success) { /* look up the name in the cache */ - n = find_name_search(&d, question, search, p->ip); + n = find_name_search(&d, question, FIND_LOCAL, p->ip); /* it is a name that already failed DNS lookup or it's expired */ if (n && (n->source == DNSFAIL || @@ -644,10 +653,15 @@ void reply_name_query(struct packet_struct *p) putip(&rdata[2],(char *)&retip); } + /* see rfc1002.txt 4.2.13 */ + reply_netbios_packet(p,nmb->header.name_trn_id, - rcode,NMB_QUERY,0,True, - &nmb->question.question_name, - 0x20, 0x01, - ttl, - rdata, success ? 6 : 0); + rcode,NMB_QUERY,0, + (query_is_to_wins_server && acting_as_wins_server ? + True : False), /* recursion_available flag */ + True, /* recursion_desired_flag */ + &nmb->question.question_name, + 0x20, 0x01, + ttl, + rdata, success ? 6 : 0); } diff --git a/source/nmbsync.c b/source/nmbsync.c index fd85c82e2cd..f2161f631af 100644 --- a/source/nmbsync.c +++ b/source/nmbsync.c @@ -20,6 +20,8 @@ */ +/* We *must have REPLACE_GETPASS defined here before the includes. */ +#define REPLACE_GETPASS #include "includes.h" extern int ClientNMB; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index 8c048ad0798..ad9bf83886d 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -1395,11 +1395,26 @@ check if a config file has changed date BOOL lp_file_list_changed(void) { struct file_lists *f = file_lists; - while (f) { + DEBUG(6,("lp_file_list_changed()\n")); + + while (f) + { pstring n2; + time_t mod_time; + strcpy(n2,f->name); standard_sub_basic(n2); - if (f->modtime != file_modtime(n2)) return(True); + + DEBUG(6,("file %s -> %s last mod_time: %s\n", + f->name, n2, ctime(&f->modtime))); + + mod_time = file_modtime(n2); + + if (f->modtime != mod_time) + { + DEBUG(6,("file %s modified: %s\n", n2, ctime(&mod_time))); + return(True); + } f = f->next; } return(False); diff --git a/source/printing/printing.c b/source/printing/printing.c index c4dd9803ebe..c83d2169891 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -929,8 +929,8 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, if (!printername || !*printername) { - DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n", - lp_servicename(snum),snum)); + DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n", + lp_servicename(snum),snum)); printername = lp_servicename(snum); } @@ -1080,3 +1080,23 @@ void status_printjob(int cnum,int snum,int jobid,int status) } + +/**************************************************************************** +we encode print job numbers over the wire so that when we get them back we can +tell not only what print job they are but also what service it belongs to, +this is to overcome the problem that windows clients tend to send the wrong +service number when doing print queue manipulation! +****************************************************************************/ +int printjob_encode(int snum, int job) +{ + return ((snum&0xFF)<<8) | (job & 0xFF); +} + +/**************************************************************************** +and now decode them again ... +****************************************************************************/ +void printjob_decode(int jobid, int *snum, int *job) +{ + (*snum) = (jobid >> 8) & 0xFF; + (*job) = jobid & 0xFF; +} diff --git a/source/script/mkproto.awk b/source/script/mkproto.awk index 08b13d46108..f2b76f20c97 100644 --- a/source/script/mkproto.awk +++ b/source/script/mkproto.awk @@ -64,7 +64,7 @@ BEGIN { next; } -!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^shm_offset_t/ { +!/^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types/ { next; } diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index e21021c0ac5..55e293d7ffd 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -480,7 +480,7 @@ static void fill_printjob_info(int cnum, int snum, int uLevel, /* the client expects localtime */ t -= TimeDiff(t); - PACKI(desc,"W",((snum%0xFF)<<8) | (queue->job%0xFF)); /* uJobId */ + PACKI(desc,"W",printjob_encode(snum, queue->job)); /* uJobId */ if (uLevel == 1) { PACKS(desc,"B21",queue->user); /* szUserName */ PACKS(desc,"B",""); /* pad */ @@ -1405,11 +1405,10 @@ static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data, char *str1 = param+2; char *str2 = skip_string(str1,1); char *p = skip_string(str2,1); - int jobid = (SVAL(p,0)&0xFF); /* the snum and jobid are encoded - by the print queue api */ - int snum = (SVAL(p,0)>>8); + int jobid, snum; int i, count; + printjob_decode(SVAL(p,0), &snum, &jobid); /* check it's a supported varient */ if (!(strcsequal(str1,"W") && strcsequal(str2,""))) @@ -1429,7 +1428,7 @@ static BOOL api_RDosPrintJobDel(int cnum,uint16 vuid, char *param,char *data, count = get_printqueue(snum,cnum,&queue,NULL); for (i=0;i>8); + int jobid, snum; int uLevel = SVAL(p,2); int function = SVAL(p,4); /* what is this ?? */ int i; char *s = data; + + printjob_decode(SVAL(p,0), &snum, &jobid); *rparam_len = 4; *rparam = REALLOC(*rparam,*rparam_len); @@ -1565,7 +1564,7 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, lpq_reset(snum); count = get_printqueue(snum,cnum,&queue,NULL); for (i=0;i> 8; /*## valid serice number??*/ - job = uJobId & 0xFF; + printjob_decode(SVAL(p,0), &snum, &job); if (snum < 0 || !VALID_SNUM(snum)) return(False); count = get_printqueue(snum,cnum,&queue,&status); for (i = 0; i < count; i++) { - if ((queue[i].job % 0xFF) == job) break; + if ((queue[i].job & 0xFF) == job) break; } if (mdrcnt > 0) *rdata = REALLOC(*rdata,mdrcnt); desc.base = *rdata; diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c index 96e787b07fb..a08402a85ea 100644 --- a/source/smbd/mangle.c +++ b/source/smbd/mangle.c @@ -414,9 +414,9 @@ static void do_fwd_mangled_map(char *s, char *MangledMap) while (*start) { while ((*start) && (*start != '(')) start++; - start++; /* Skip the ( */ if (!*start) continue; /* Always check for the end. */ + start++; /* Skip the ( */ end = start; /* Search for the ' ' or a ')' */ DEBUG(5,("Start of first in pair '%s'\n", start)); while ((*end) && !((*end == ' ') || (*end == ')'))) diff --git a/source/smbd/password.c b/source/smbd/password.c index 2740304cc4f..ed79d658a66 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -1576,11 +1576,25 @@ BOOL server_cryptkey(char *buf) p = outbuf+len; name_mangle(desthost,p,' '); len += name_len(p); + p = outbuf+len; /* and my name */ - p = outbuf+len; - name_mangle(remote_machine,p,' '); - len += name_len(p); + /* Fix from Frank Varnavas . + We cannot use the same name as the client to + the NT password server, as NT will drop client + connections if the same client name connects + twice. Instead, synthesize a name from our pid. + and the remote machine name. + */ + { + char buf[32]; /* create name as PIDname */ + sprintf(buf,"%d", getpid()); + strncpy(&buf[strlen(buf)], remote_machine, 31 - strlen(buf)); + buf[31] = '\0'; + DEBUG(1,("negprot w/password server as %s\n",buf)); + name_mangle(buf,p,' '); + len += name_len(p); + } _smb_setlen(outbuf,len); CVAL(outbuf,0) = 0x81; diff --git a/source/smbd/reply.c b/source/smbd/reply.c index cadd63e0457..773063131af 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -261,7 +261,26 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (connection_num < 0) return(connection_error(inbuf,outbuf,connection_num)); - set_message(outbuf,2,strlen(devicename)+1,True); + if (Protocol < PROTOCOL_NT1) + { + set_message(outbuf,2,strlen(devicename)+1,True); + strcpy(smb_buf(outbuf),devicename); + } + else + { + char *fsname = "NTFS"; + char *p; + + set_message(outbuf,3,3,True); + + p = smb_buf(outbuf); + strcpy(p,devicename); p = skip_string(p,1); /* device name */ + strcpy(p,fsname); p = skip_string(p,1); /* filesystem type e.g NTFS */ + + set_message(outbuf,3,PTR_DIFF(p,smb_buf(outbuf)),False); + + SSVAL(outbuf, smb_vwv2, 0x0); /* optional support */ + } DEBUG(3,("%s tconX service=%s user=%s cnum=%d\n",timestring(),service,user,connection_num)); @@ -269,8 +288,6 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) SSVAL(inbuf,smb_tid,connection_num); SSVAL(outbuf,smb_tid,connection_num); - strcpy(smb_buf(outbuf),devicename); - return chain_reply(inbuf,outbuf,length,bufsize); } @@ -350,8 +367,24 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) } else { uint16 passlen1 = SVAL(inbuf,smb_vwv7); uint16 passlen2 = SVAL(inbuf,smb_vwv8); + uint32 client_caps = IVAL(inbuf,smb_vwv11); + enum remote_arch_types ra_type = get_remote_arch(); + char *p = smb_buf(inbuf); + /* client_caps is used as final determination if client is NT or Win95. + This is needed to return the correct error codes in some + circumstances. + */ + + if(ra_type == RA_WINNT || ra_type == RA_WIN95) + { + if(client_caps & (CAP_NT_SMBS | CAP_STATUS32)) + set_remote_arch( RA_WINNT); + else + set_remote_arch( RA_WIN95); + } + if (passlen1 != 24 && passlen2 != 24) doencrypt = False; @@ -2463,7 +2496,7 @@ int reply_printqueue(char *inbuf,char *outbuf) { put_dos_date2(p,0,queue[i].time); CVAL(p,4) = (queue[i].status==LPQ_PRINTING?2:3); - SSVAL(p,5,queue[i].job); + SSVAL(p,5,printjob_encode(SNUM(cnum), queue[i].job)); SIVAL(p,7,queue[i].size); CVAL(p,11) = 0; StrnCpy(p+12,queue[i].user,16); diff --git a/source/smbd/server.c b/source/smbd/server.c index aaf62fdcad9..24dc8fb51f4 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -397,7 +397,7 @@ static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) if (!name_map_mangle(name2,False,SNUM(cnum))) continue; if ((mangled && mangled_equal(name,name2)) - || fname_equal(name, dname)) + || fname_equal(name, name2)) /* name2 here was changed to dname - since 1.9.16p2 - not sure of reason (jra) */ { /* we've found the file, change it's name and return */ if (docache) DirCacheAdd(path,name,dname,SNUM(cnum)); @@ -1532,7 +1532,12 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, if (strstr(fname,".+,;=[].")) { unix_ERR_class = ERRDOS; + /* OS/2 Workplace shell fix - may be main code stream in a later release. */ +#ifdef OS2_WPS_FIX + unix_ERR_code = ERRcannotopen; +#else /* OS2_WPS_FIX */ unix_ERR_code = ERROR_EAS_NOT_SUPPORTED; +#endif /* OS2_WPS_FIX */ return; } @@ -1978,6 +1983,19 @@ struct {0,0,0} }; +/* Mapping for old clients. */ + +struct +{ + int new_smb_error; + int old_smb_error; + int protocol_level; + enum remote_arch_types valid_ra_type; +} old_client_errmap[] = +{ + {ERRbaddirectory, ERRbadpath, (int)PROTOCOL_NT1, RA_WINNT}, + {0,0,0} +}; /**************************************************************************** create an error packet from errno @@ -1998,17 +2016,40 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int else { while (unix_smb_errmap[i].smbclass != 0) - { - if (unix_smb_errmap[i].unixerror == errno) + { + if (unix_smb_errmap[i].unixerror == errno) { eclass = unix_smb_errmap[i].smbclass; ecode = unix_smb_errmap[i].smbcode; break; } i++; - } + } } + /* Make sure we don't return error codes that old + clients don't understand. */ + + /* JRA - unfortunately, WinNT needs some error codes + for apps to work correctly, Win95 will break if + these error codes are returned. But they both + negotiate the *same* protocol. So we need to use + the revolting 'remote_arch' enum to tie break. + + There must be a better way of doing this... + */ + + for(i = 0; old_client_errmap[i].new_smb_error != 0; i++) + { + if(((Protocol < old_client_errmap[i].protocol_level) || + (old_client_errmap[i].valid_ra_type != get_remote_arch())) && + (old_client_errmap[i].new_smb_error == ecode)) + { + ecode = old_client_errmap[i].old_smb_error; + break; + } + } + return(error_packet(inbuf,outbuf,eclass,ecode,line)); } @@ -3025,7 +3066,6 @@ struct { ****************************************************************************/ static int reply_negprot(char *inbuf,char *outbuf) { - extern fstring remote_arch; int outsize = set_message(outbuf,1,0,True); int Index=0; int choice= -1; @@ -3065,22 +3105,22 @@ static int reply_negprot(char *inbuf,char *outbuf) switch ( arch ) { case ARCH_SAMBA: - strcpy(remote_arch,"Samba"); + set_remote_arch(RA_SAMBA); break; case ARCH_WFWG: - strcpy(remote_arch,"WfWg"); + set_remote_arch(RA_WFWG); break; case ARCH_WIN95: - strcpy(remote_arch,"Win95"); + set_remote_arch(RA_WIN95); break; case ARCH_WINNT: - strcpy(remote_arch,"WinNT"); + set_remote_arch(RA_WINNT); break; case ARCH_OS2: - strcpy(remote_arch,"OS2"); + set_remote_arch(RA_OS2); break; default: - strcpy(remote_arch,"UNKNOWN"); + set_remote_arch(RA_UNKNOWN); break; } @@ -3471,12 +3511,12 @@ void exit_server(char *reason) /**************************************************************************** do some standard substitutions in a string ****************************************************************************/ -void standard_sub(int cnum,char *string) +void standard_sub(int cnum,char *str) { if (VALID_CNUM(cnum)) { char *p, *s, *home; - for ( s=string ; (p=strchr(s, '%')) != NULL ; s=p ) { + for ( s=str ; (p=strchr(s, '%')) != NULL ; s=p ) { switch (*(p+1)) { case 'H' : if ((home = get_home_dir(Connections[cnum].user))!=NULL) string_sub(p,"%H",home); @@ -3492,7 +3532,7 @@ void standard_sub(int cnum,char *string) } } } - standard_sub_basic(string); + standard_sub_basic(str); } /* diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 80529240590..19c1158658c 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -341,7 +341,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l strcpy(pathreal,Connections[cnum].dirpath); if(needslash) strcat(pathreal,"/"); - strcat(pathreal,fname); + strcat(pathreal,dname); if (sys_stat(pathreal,&sbuf) != 0) { DEBUG(5,("get_lanman2_dir_entry:Couldn't stat [%s] (%s)\n",pathreal,strerror(errno))); @@ -368,13 +368,11 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l } } - + name_map_mangle(fname,False,SNUM(cnum)); p = pdata; nameptr = p; - name_map_mangle(fname,False,SNUM(cnum)); - nt_extmode = mode ? mode : NT_FILE_ATTRIBUTE_NORMAL; switch (info_level) @@ -1301,11 +1299,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, if (total_data > 0 && IVAL(pdata,0) == total_data) { /* uggh, EAs for OS2 */ DEBUG(4,("Rejecting EA request with total_data=%d\n",total_data)); -#ifdef OS2_WPS_FIX /* This may become the main code stream in a later release */ - return(ERROR(ERRDOS,ERRcannotopen)); -#else /* OS2_WPS_FIX */ return(ERROR(ERRDOS,ERROR_EAS_NOT_SUPPORTED)); -#endif /* OS2_WPS_FIX */ } switch (info_level) -- cgit v1.2.1 From 63c4dc3c69a0ca49e94af94cc9375ba08d2f8b53 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 1997 20:40:34 +0000 Subject: Bringing 1.9.17 patch tree up to date for documentation. Preparing to release 1.9.17p1. Jeremy (jallison@whistle.com) --- WHATSNEW.txt | 41 +++++++++++++++++++++++++++++---- docs/MIRRORS | 33 --------------------------- docs/announce | 2 +- docs/faq/sambafaq-3.html | 2 +- docs/faq/sambafaq.sgml | 2 +- docs/faq/sambafaq.txt | 2 +- docs/history | 2 +- docs/manpages/smb.conf.5 | 11 ++++++--- docs/samba.faq | 2 +- docs/textdocs/BROWSING.txt | 4 ++-- docs/textdocs/DIAGNOSIS.txt | 11 ++++++++- docs/textdocs/DOMAIN.txt | 42 ++++++++++++++++------------------ docs/textdocs/DOMAIN_CONTROL.txt | 2 +- docs/textdocs/GOTCHAS.txt | 4 ++-- docs/textdocs/Passwords.txt | 2 +- docs/textdocs/Support.txt | 49 ++++++++++++++++++++++++++++++++++++++-- docs/textdocs/UNIX-SMB.txt | 4 ++-- docs/textdocs/UNIX_INSTALL.txt | 2 +- 18 files changed, 136 insertions(+), 81 deletions(-) delete mode 100644 docs/MIRRORS diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 6719d439e4f..500a4726bf2 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,8 +1,41 @@ - WHATS NEW IN 1.9.17 - August 25th 1997 - ====================================== + WHATS NEW IN 1.9.17p1 - September 5 1997 + ======================================== -New stable release of Samba. ----------------------------- +New stable patch release: Samba - version 1.9.17p1. +--------------------------------------------------- + +This is a patch release which superceedes the +last stable release of Samba, release 1.9.17. +This release fixes the few bugs that users reported +in the previous stable release (1.9.17). + +These bugfixes are : + +Fix for DOS and Windows 95 clients having trouble +delting files on a Samba share in a DOS command line +environment. + +Fixes to set the 'flag' bits correctly when talking to a +non-Samba WINS server. + +Fix for NT clients being dropped when using security=server. + +Fixes to the printer queue reporting code. + +Fix for the name map mangle bug (mangling .html -> .htm was +not working). + +If you are not affected by any of these problems then there +is no need to upgrade. + +The release notes from the previous stable release follow. + +The Samba Team. + +-------------Previous release notes------------------------- + +New stable release of Samba - 1.9.17 +------------------------------------ This is the new stable release of Samba, superceeding the last stable release 1.9.16p11. All users are diff --git a/docs/MIRRORS b/docs/MIRRORS deleted file mode 100644 index a055860e999..00000000000 --- a/docs/MIRRORS +++ /dev/null @@ -1,33 +0,0 @@ -The main Samba ftp site is samba.anu.edu.au in pub/samba/. Contact -samba-bugs@samba.anu.edu.au for help with this site. - -Mirror sites include: - -ftp://nimbus.anu.edu.au/pub/tridge/samba -ftp://sunsite.auc.dk/pub/unix/networking/samba/ -ftp://src.doc.ic.ac.uk/packages/samba/ -ftp://choc.satech.net.au/pub/samba/ -ftp://ftp.uni-trier.de/pub/unix/network/samba/ -ftp://sunsite.mff.cuni.cz/Net/Protocols/Samba/ -ftp://ring.aist.go.jp/archives/net/samba/ -ftp://ring.asahi-net.or.jp/archives/net/samba/ -ftp://ftp.cs.ucr.edu/pub/software/samba -ftp://ftp.ua.pt/pub/misc/samba/ -ftp://sunsite.unc.edu/pub/Linux/system/Network/samba/ - -There are several others. Give archie a try. - -SCO binaries available from: -ftp://ftp.markv.com/pub/samba (built by lance@fox.com) - -AIX and DEC OSF/1 binaries are available from: -ftp://151.99.220.5/pub/samba (built by davide.migliavacca@inferentia.inet.it) - -QNX binaries and source code: -ftp://quics.qnx.com/usr/free/staging/samba - -Http sites include: - -http://samba.canberra.edu.au/pub/samba -http://www.choc.satech.net.au/pub/samba/ - diff --git a/docs/announce b/docs/announce index 18e34b68c2b..adcde8966f8 100644 --- a/docs/announce +++ b/docs/announce @@ -28,7 +28,7 @@ allows you to access a SMB printer (such as one attached to an OS/2 or WfWg server) from Unix, using an entry in /etc/printcap, or by explicitly specifying the command used to print files. -What are it's features? +What are its features? ------------------------ Samba supports many features that are not supported in other SMB diff --git a/docs/faq/sambafaq-3.html b/docs/faq/sambafaq-3.html index 39cded21ec1..8b24de54f23 100644 --- a/docs/faq/sambafaq-3.html +++ b/docs/faq/sambafaq-3.html @@ -85,7 +85,7 @@ To syncronize your PC's clock with your Samba server: Each time you start your computer (or login for Win95) your PC will -synchronize it's clock with your Samba server.

+synchronize its clock with your Samba server.

Alternativley, if you clients support Domain Logons, you can setup Domain Logons with Samba - see: BROWSING.txt *** for more information.

diff --git a/docs/faq/sambafaq.sgml b/docs/faq/sambafaq.sgml index 7a618d47c8f..951ad822edb 100644 --- a/docs/faq/sambafaq.sgml +++ b/docs/faq/sambafaq.sgml @@ -570,7 +570,7 @@ To syncronize your PC's clock with your Samba server: Close the properties dialog box by choosing 'OK' Each time you start your computer (or login for Win95) your PC will -synchronize it's clock with your Samba server. +synchronize its clock with your Samba server. Alternativley, if you clients support Domain Logons, you can setup Domain Logons with Samba - see: *** for more information. diff --git a/docs/faq/sambafaq.txt b/docs/faq/sambafaq.txt index 2bc45fb7945..e7f5f32a20d 100644 --- a/docs/faq/sambafaq.txt +++ b/docs/faq/sambafaq.txt @@ -841,7 +841,7 @@ o Close the properties dialog box by choosing 'OK' Each time you start your computer (or login for Win95) your PC will - synchronize it's clock with your Samba server. + synchronize its clock with your Samba server. Alternativley, if you clients support Domain Logons, you can setup Domain Logons with Samba - see: BROWSING.txt diff --git a/docs/history b/docs/history index a86160e854d..dd9e83719ff 100644 --- a/docs/history +++ b/docs/history @@ -112,7 +112,7 @@ code! I wrote back saying it was OK, but never heard from him again. I don't know if it went on the cd-rom. Anyway, the next big event was in December 1993, when Dan again sent -me an e-mail saying my server had "raised it's ugly head" on +me an e-mail saying my server had "raised its ugly head" on comp.protocols.tcpip.ibmpc. I had a quick look on the group, and was surprised to see that there were people interested in this thing. diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5 index 1eed1fcd868..a0a96f26ff6 100644 --- a/docs/manpages/smb.conf.5 +++ b/docs/manpages/smb.conf.5 @@ -1585,7 +1585,7 @@ see "debug level" .SS logon path (G) This parameter specifies the home directory where roaming profiles -(USER.DAT / USER.MAN files) are stored. +(USER.DAT / USER.MAN files for Windows 95) are stored. This option takes the standard substitutions, allowing you to have separate logon scripts for each user or machine. It also specifies @@ -1603,11 +1603,16 @@ be made read-only. It is not adviseable that the USER.DAT file be made read-only - rename it to USER.MAN to achieve the desired effect (a MANdatory profile). +Windows clients can sometimes maintain a connection to the [homes] +share, even though there is no user logged in. Therefore, it is +vital that the logon path does not include a reference to the +homes share (i.e \\\\%L\\HOMES\profile_path will cause problems). + .B Default: - logon path = \\\\%L\\%U + logon path = \\\\%L\\%U\\profile .B Example: - logon path = \\\\PROFILESERVER\\HOME_DIR\\%U + logon path = \\\\PROFILESERVER\\HOME_DIR\\%U\\PROFILE .SS logon script (G) diff --git a/docs/samba.faq b/docs/samba.faq index e74585b9769..19126439500 100644 --- a/docs/samba.faq +++ b/docs/samba.faq @@ -605,7 +605,7 @@ To syncronize your PC's clock with your Samba server: * Close the properties dialog box by choosing 'OK' Each time you start your computer (or login for Win95) your PC will -synchronize it's clock with your Samba server. +synchronize its clock with your Samba server. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/textdocs/BROWSING.txt b/docs/textdocs/BROWSING.txt index 12d3417a294..d8362f15299 100644 --- a/docs/textdocs/BROWSING.txt +++ b/docs/textdocs/BROWSING.txt @@ -320,7 +320,7 @@ all smb.conf files : wins server = where is either the DNS name of the WINS server -machine or it's IP address. +machine or its IP address. Note that this line MUST NOT BE SET in the smb.conf file of the Samba server acting as the WINS server itself. If you set both the @@ -358,7 +358,7 @@ server as a domain master browser set the following option in the domain master = yes The domain master browser should also preferrably be the local master -browser for it's own subnet. In order to achieve this set the following +browser for its own subnet. In order to achieve this set the following options in the [global] section of the smb.conf file : domain master = yes diff --git a/docs/textdocs/DIAGNOSIS.txt b/docs/textdocs/DIAGNOSIS.txt index 5f20f610310..11eb91b2ff8 100644 --- a/docs/textdocs/DIAGNOSIS.txt +++ b/docs/textdocs/DIAGNOSIS.txt @@ -69,7 +69,12 @@ run ping. If you get a message saying "host not found" or similar then your DNS software or /etc/hosts file is not correctly setup. It is possible to run samba without DNS entries for the server and client, but I assume -you do have correct entries for the remainder of these tests. +you do have correct entries for the remainder of these tests. + +Another reason why ping might fail is if your host is running firewall +software. You will need to relax the rules to let in the workstation +in question, perhaps by allowing access from another subnet (on Linux +this is done via the ipfwadm program.) TEST 3: @@ -208,6 +213,10 @@ same fixes apply as they did for the "smbclient -L" test above. In particular, make sure your "hosts allow" line is correct (see the man pages) +If you get "specified computer is not receiving requests" or similar +it probably means that the host is not contactable via tcp services. +Check to see if the host is running tcp wrappers, and if so add an entry in +the hosts.allow file for your client (or subnet, etc.) TEST 9: diff --git a/docs/textdocs/DOMAIN.txt b/docs/textdocs/DOMAIN.txt index 547e1b6cf8c..3cd8a125b7b 100644 --- a/docs/textdocs/DOMAIN.txt +++ b/docs/textdocs/DOMAIN.txt @@ -1,30 +1,21 @@ Contributor: Samba Team -Updated: August 25, 1997 +Updated: June 27, 1997 Subject: Network Logons and Roving Profiles =========================================================================== A domain and a workgroup are exactly the same thing in terms of network -traffic, except for the client logon sequence. Some kind of distributed -authentication database is associated with a domain (there are quite a few -choices) and this adds so much flexibility that many people think of a -domain as a completely different entity to a workgroup. From Samba's -point of view a client connecting to a service presents an authentication -token, and it if it is valid they have access. Samba does not care what -mechanism was used to generate that token in the first place. +browsing. The difference is that a distributable authentication +database is associated with a domain, for secure login access to a +network. Also, different access rights can be granted to users if they +successfully authenticate against a domain logon server (samba does not +support this, but NT server and other systems based on NT server do). The SMB client logging on to a domain has an expectation that every other server in the domain should accept the same authentication information. However the network browsing functionality of domains and workgroups is identical and is explained in BROWSING.txt. -There are some implementation differences: Windows 95 can be a member of -both a workgroup and a domain, but Windows NT cannot. Windows 95 also -has the concept of an "alternative workgroup". Samba can only be a -member of a single workgroup or domain, although this is due to change -with a future version when nmbd will be split into two daemons, one -for WINS and the other for browsing (NetBIOS.txt explains what WINS is.) - Issues related to the single-logon network model are discussed in this document. Samba supports domain logons, network logon scripts, and user profiles. The support is still experimental, but it seems to work. @@ -32,10 +23,8 @@ profiles. The support is still experimental, but it seems to work. The support is also not complete. Samba does not yet support the sharing of the Windows NT-style SAM database with other systems. However this is only one way of having a shared user database: exactly the same effect can -be achieved by having all servers in a domain share a distributed NIS, -Kerberos or other authentication database. These other options may or may -not involve changes to the client software, that depends on the combination -of client OS, server OS and authentication protocol. +be achieved by having all servers in a domain share a distributed NIS or +Kerberos authentication database. When an SMB client in a domain wishes to logon it broadcast requests for a logon server. The first one to reply gets the job, and validates its @@ -147,8 +136,9 @@ In the [global] section of smb.conf set the following (for example): logon path = \\profileserver\profileshare\profilepath\%U\moreprofilepath -The default for this option is \\%L\%U, namely \\sambaserver\username, -The \\L%\%U services is created automatically by the [homes] service. +The default for this option is \\%L\%U\profile, namely +\\sambaserver\username\profile. The \\L%\%U services is created +automatically by the [homes] service. If you are using a samba server for the profiles, you _must_ make the share specified in the logon path browseable. Windows 95 appears to @@ -158,6 +148,10 @@ away. It also attempts to create the components of the full path for you. If the creation of any component fails, or if it cannot see any component of the path, the profile creation / reading fails. +[lkcl 26aug96 - we have discovered a problem where Windows clients can +maintain a connection to the [homes] share in between logins. The +[homes] share must NOT therefore be used in a profile path.] + Windows 95 ---------- @@ -281,8 +275,10 @@ to specify the location of the profile. Samba cannot be a domain logon server for NT, therefore you will need to manually configure each and every account. [lkcl 10aug97 - i tried setting the path in each account to \\samba-server\homes\profile, and discovered that -this fails for some reason. you have to have \\samba-server\user\profile, -where user is the username created from the [homes] share]. +this fails because a background process maintains the connection to +the [homes] share which does _not_ close down in between user logins. +you have to have \\samba-server\user\profile, where user is the +username created from the [homes] share]. The entry for the NT 4.0 profile is a _directory_ not a file. The NT help on profiles mentions that a directory is also created with a .PDS diff --git a/docs/textdocs/DOMAIN_CONTROL.txt b/docs/textdocs/DOMAIN_CONTROL.txt index bebac3e900c..0b077320cdb 100644 --- a/docs/textdocs/DOMAIN_CONTROL.txt +++ b/docs/textdocs/DOMAIN_CONTROL.txt @@ -94,7 +94,7 @@ have at least one Backup Domain Controller (BDC). The PDC and BDCs then participate in replication of the SAM database so that each Domain Controlling participant will have an up to date SAM component -within it's registry. +within its registry. Samba can NOT at this time function as a Domain Controller for any of these security services, but like all other domain members can interact with the diff --git a/docs/textdocs/GOTCHAS.txt b/docs/textdocs/GOTCHAS.txt index d4e5f3e842d..bc5c6dae853 100644 --- a/docs/textdocs/GOTCHAS.txt +++ b/docs/textdocs/GOTCHAS.txt @@ -48,10 +48,10 @@ Details: Windows NT checks at start up to see if any domain logon controllers are already running within the domain. It finds Samba claiming to offer the service and therefore does NOT - start it's Network Logon Service. + start its Network Logon Service. Windows NT needs the Windows NT network logon service to gain - from it's Domain controller's SAM database the security + from its Domain controller's SAM database the security identifier for the user loging on. Work-around: Stop the Samba nmbd and smbd processes, then on the Windows diff --git a/docs/textdocs/Passwords.txt b/docs/textdocs/Passwords.txt index 3d7acac9dd3..f76010c4608 100644 --- a/docs/textdocs/Passwords.txt +++ b/docs/textdocs/Passwords.txt @@ -37,7 +37,7 @@ only written and tested for AFS 3.3 and later. SECURITY = SERVER ================= -Samba can use a remote server to do it's username/password +Samba can use a remote server to do its username/password validation. This allows you to have one central machine (for example a NT box) control the passwords for the Unix box. diff --git a/docs/textdocs/Support.txt b/docs/textdocs/Support.txt index a4fd34aca62..afffc2be505 100644 --- a/docs/textdocs/Support.txt +++ b/docs/textdocs/Support.txt @@ -17,6 +17,8 @@ If you want to be added to the list, or want your entry modified then contact the address below. Please make sure to include a header line giving the region and country, eg CANBERRA - AUSTRALIA. +The Samba Team reserves the right not to add support providers. + You can contact the maintainers at samba-bugs@samba.anu.edu.au The support list has now been re-arranged into geographical areas @@ -27,7 +29,7 @@ Region Number of entries ---------------------------------------------------- AFRICA 2 AMERICA - CENTRAL & SOUTH 3 - AMERICA - USA 31 + AMERICA - USA 33 ASIA 1 AUSTRALIA & NEW ZEALAND 18 CANADA 8 @@ -299,7 +301,7 @@ Email: jay@wss.net ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -FORT COLLINS, CO - USA +FORT COLLINS, COLORADO - USA Granite Computing Solutions ATTN: Brian Grossman @@ -314,6 +316,23 @@ WWW solutions. WWW education. Unix education. Custom software development - eg. http://www.SoftHome.Net/modsim/. ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +COLORADO - USA + +Daylight Software +1062 Lexington Lane +Estes Park, CO 80517 USA +(970) 586-6058 + +We have experience with Samba under SunOS, Solaris and Linux, +and also with Windows NT and Microsoft Lan Manager. + +Contact: daylight@frii.net + +Chris Howard Daylight Software +daylight@frii.net Estes Park, Colorado USA +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ FLORIDA - USA @@ -384,6 +403,32 @@ Florida area. We are well familiar in the integration of SAMBA and NT and in SAMBA configuration on AIX, SCO, Linux And SUN Solaris. ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +FLORIDA - USA + +The PC Doctor +Tampa Bay Interactive +1314 Tampa Rd STE 120 +Palm Harbor, FL 34683 + +ph 813.781-2209 +fx 813.571-3805 + +Contacts: Jared Hall: jhall@tbi.net + System Operations: support@tbi.net + +Tampa Bay Interactive provides complete Internet solutions for the Small +Office and Home Office. Specializing in Intel-Based UNIX systems; Linux, +BSD/OS, FreeBSD, SCO. Proxy Server specialists. + +~~ Jared Hall ~~~~~~~ Tampa Bay Interactive +~~~~~~~~~~~~~~~~~~~~~ 1314 Tampa Rd, #120 +~~ jhall@tbi.net ~~~~ Palm Harbor, FL 34683 +~~ (813) 781-2209 ~~~ (http://www.tbi.net) + +Telecom Corner - http://www.tbi.net/~jhall +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ GEORGIA - USA diff --git a/docs/textdocs/UNIX-SMB.txt b/docs/textdocs/UNIX-SMB.txt index 88a7324dd73..ec2e657c052 100644 --- a/docs/textdocs/UNIX-SMB.txt +++ b/docs/textdocs/UNIX-SMB.txt @@ -88,7 +88,7 @@ passwords they are in trouble. Samba can try to cope with this by either using the "password level" option which causes Samba to try the offered password with up to the specified number of case changes, or by using the "password server" -option which allows Samba to do it's validation via another machine +option which allows Samba to do its validation via another machine (typically a WinNT server). Samba supports the password encryption method used by SMB @@ -128,7 +128,7 @@ The second major problem is the "opportunistic locking" requested by some clients. If a client requests opportunistic locking then it is asking the server to notify it if anyone else tries to do something on the same file, at which time the client will say if it is willing to -give up it's lock. Unix has no simple way of implementing +give up its lock. Unix has no simple way of implementing opportunistic locking, and currently Samba has no support for it. Deny Modes diff --git a/docs/textdocs/UNIX_INSTALL.txt b/docs/textdocs/UNIX_INSTALL.txt index 8b430a98844..c189482ca41 100644 --- a/docs/textdocs/UNIX_INSTALL.txt +++ b/docs/textdocs/UNIX_INSTALL.txt @@ -315,7 +315,7 @@ codes of locking calls to tell clients that everything is OK. The second class of locking is the "deny modes". These are set by an application when it opens a file to determine what types of access -should be allowed simultaneously with it's open. A client may ask for +should be allowed simultaneously with its open. A client may ask for DENY_NONE, DENY_READ, DENY_WRITE or DENY_ALL. There are also special compatability modes called DENY_FCB and DENY_DOS. -- cgit v1.2.1 From d684d276fbeb9a4f53840df8a47f6ca6ede8bd55 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 5 Sep 1997 21:49:07 +0000 Subject: client.c: status.c: Ensure that myhostname is set so that substitutions work. server.c: Sync up with main branch. Jermey (jallison@whistle.com) --- source/client/client.c | 6 ++++++ source/smbd/server.c | 3 ++- source/utils/status.c | 4 ++-- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/source/client/client.c b/source/client/client.c index 329956ce94b..4718db84ac0 100644 --- a/source/client/client.c +++ b/source/client/client.c @@ -34,6 +34,7 @@ pstring cd_path = ""; pstring service=""; pstring desthost=""; extern pstring myname; +extern pstring myhostname; pstring password = ""; pstring username=""; pstring workgroup=""; @@ -4625,6 +4626,11 @@ static void usage(char *pname) DEBUG(3,("%s client started (version %s)\n",timestring(),VERSION)); + if(!get_myname(myhostname,NULL)) + { + DEBUG(0,("Failed to get my hostname.\n")); + } + if (!lp_load(servicesf,True)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); } diff --git a/source/smbd/server.c b/source/smbd/server.c index 24dc8fb51f4..d4407269f0b 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -1532,12 +1532,13 @@ void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, if (strstr(fname,".+,;=[].")) { unix_ERR_class = ERRDOS; - /* OS/2 Workplace shell fix - may be main code stream in a later release. */ + /* OS/2 Workplace shell fix may be main code stream in a later release. */ #ifdef OS2_WPS_FIX unix_ERR_code = ERRcannotopen; #else /* OS2_WPS_FIX */ unix_ERR_code = ERROR_EAS_NOT_SUPPORTED; #endif /* OS2_WPS_FIX */ + return; } diff --git a/source/utils/status.c b/source/utils/status.c index b439741e6c6..6fa85c0a630 100644 --- a/source/utils/status.c +++ b/source/utils/status.c @@ -188,13 +188,13 @@ locking version (was %d, should be %d).\n",fname, } } + get_myname(myhostname, NULL); + if (!lp_load(servicesf,False)) { fprintf(stderr, "Can't load %s - run testparm to debug it\n", servicesf); return (-1); } - get_myname(myhostname, NULL); - if (verbose) { printf("using configfile = %s\n", servicesf); printf("lockdir = %s\n", *lp_lockdir() ? lp_lockdir() : "NULL"); -- cgit v1.2.1 From 91f482026df92da804fbd0344c83807c9a2e775e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 11 Sep 1997 00:19:26 +0000 Subject: locking.c: Fix to make slow share mode file 0666 instead of 0644. Stoped smbstatus from reporting correct locks. nameelect.c: Luke's fix for elections. namepacket.c: Removed iritating error message. nmblookup.c: Fixed bug where status request went to random IP address. reply.c: Changed NTFS to SAMBA in filename string. Jeremy (jallison@whistle.com) --- source/locking/locking.c | 2 +- source/nameelect.c | 2 +- source/namepacket.c | 5 ----- source/smbd/reply.c | 2 +- source/utils/nmblookup.c | 16 ++++++++++++---- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/source/locking/locking.c b/source/locking/locking.c index f579a75a0bc..760d21a05d8 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -616,7 +616,7 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok #ifdef SECURE_SHARE_MODES fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600); #else /* SECURE_SHARE_MODES */ - fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0644); + fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); #endif /* SECURE_SHARE_MODES */ umask(old_umask); if(!become_user(cnum,Connections[cnum].vuid)) diff --git a/source/nameelect.c b/source/nameelect.c index 06f3e870af1..4666b22588c 100644 --- a/source/nameelect.c +++ b/source/nameelect.c @@ -76,7 +76,7 @@ void check_master_browser(time_t t) { if (strequal(work->work_group, myworkgroup) && !AM_MASTER(work)) { - if (lp_local_master()) + if (lp_local_master() && lp_preferred_master()) { /* potential master browser - not a master browser. force becoming a master browser, hence the log message. diff --git a/source/namepacket.c b/source/namepacket.c index d60ef9f6ae2..44e449b8c2a 100644 --- a/source/namepacket.c +++ b/source/namepacket.c @@ -199,11 +199,6 @@ void reply_netbios_packet(struct packet_struct *p1,int trn_id, p = *p1; - if (recursion_available && lp_wins_server()) - { - DEBUG(0,("reply_netbios_packet: r_a not to be used when not a WINS server\n")); - } - switch (rcv_code) { case NMB_STATUS: diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 773063131af..3ef37052dbe 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -268,7 +268,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) } else { - char *fsname = "NTFS"; + char *fsname = "SAMBA"; char *p; set_message(outbuf,3,3,True); diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c index 582f4eb6db3..25c94dcd6a0 100644 --- a/source/utils/nmblookup.c +++ b/source/utils/nmblookup.c @@ -192,17 +192,25 @@ int main(int argc,char *argv[]) retries = 1; } - if (name_query(ServerFD,lookup,lookup_type,bcast,True, + if (name_query(ServerFD,lookup,lookup_type,bcast,True, bcast_addr,&ip,NULL)) - { - printf("%s %s\n",inet_ntoa(ip),lookup); - } + { + printf("%s %s\n",inet_ntoa(ip),lookup); + + /* We can only do find_status if the ip address returned + was valid - ie. name_query returned true. + */ if (find_status) { printf("Looking up status of %s\n",inet_ntoa(ip)); name_status(ServerFD,lookup,lookup_type,True,ip,NULL,NULL,NULL); printf("\n"); } + } + else + { + printf("name_query failed to find name %s\n", lookup); + } } return(0); -- cgit v1.2.1 From 87644499eac889a4c83c05f473883488cbdb710d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 12 Sep 1997 16:31:51 +0000 Subject: Fixed bug where user connecting with guest username and no password was not being seen as guest. Bug was introduced in previous patch. Jeremy (jallison@whistle.com) --- source/smbd/reply.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 3ef37052dbe..228d8ad6692 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -459,6 +459,13 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) add_session_user(user); + /* Check if the given username was the guest user with no password. + We need to do this check after add_session_user() as that + call can potentially change the username (via map_user). + */ + + if(!guest && strequal(user,lp_guestaccount(-1)) && (*smb_apasswd == 0)) + guest = True; if (!guest && !(lp_security() == SEC_SERVER && server_validate(inbuf)) && !check_hosts_equiv(user)) -- cgit v1.2.1 From cfd4461be4522f1dd64d43e8a59f8baeed64f177 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 15 Sep 1997 20:02:20 +0000 Subject: Keep consultants in sync. --- docs/textdocs/Support.txt | 59 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/docs/textdocs/Support.txt b/docs/textdocs/Support.txt index afffc2be505..6257872098a 100644 --- a/docs/textdocs/Support.txt +++ b/docs/textdocs/Support.txt @@ -29,11 +29,11 @@ Region Number of entries ---------------------------------------------------- AFRICA 2 AMERICA - CENTRAL & SOUTH 3 - AMERICA - USA 33 + AMERICA - USA 35 ASIA 1 AUSTRALIA & NEW ZEALAND 18 CANADA 8 - EUROPE 33 + EUROPE 34 MIDDLE EAST 1 AFRICA @@ -223,6 +223,28 @@ To find out more about our company, look at our website: http://www.acclaim.com ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +BAY AREA, BERKELEY CALIFORNIA - USA + +Vortex Technology Services + +2467 Warring St Suite 206, Berkeley CA 94704 + +Phone/Fax : (510) 540-VTEX E-Mail: support@vtex.net + (510) 540-8839 + +Contact: Paul Puey, Chief Network Consultant/Engineer + +Vortex Technology is a fast growing technical service company based in +Berkeley, California. Our Co-founders are composed entirely of UC +Berkeley engineering graduates with a broad range of skills in the +technical consultation fields. We provide bay area companies with +professional web site and database design, LAN and WAN consultation, and +custom programming. We ourselves use a mixed NT / Linux Samba server +environment in our office. We are very experienced with Samba +administration as well as administration of UNIX and NT networks. +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ CALIFORNIA - USA @@ -628,6 +650,23 @@ US dollars per hour. Please contact us for more information on our rates and services. ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +TEXAS - USA + +The Solutions Group +P.O. Box 31400 +Houston, TX 77231-1400 + +Voice: (713) 729-2602 +Fax: (713) 723-9387 +Email: chuckb@LinuxTX.com + +The Solutions Group provides support for Linux, Solaris, and SCO UNIX. +We specialize in mixed environments using Samba. We are certified NT +as well as UNIX specialists. We can provide onsite support in the +Houston area and remote support in any other areas. +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ UNITED STATES @@ -1591,6 +1630,22 @@ Digital Unix Macintosh ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +ROME - ITALY + +Company: Pantheon Srl + Via del Tritone 132 + 00187 ROME - ITALY + +Phone/Fax: +39 6 47823666 +URL: http://www.pantheon.it + +Contact: Dario Centofanti + +Pantheon provide support for SaMBa and other TCP/IP applications running +under Linux. We are also an internet provider. +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ VICENZA - ITALY -- cgit v1.2.1 From f8998b9dac5c86e5a12f730837aa7f24c24f1bf1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 17 Sep 1997 17:08:00 +0000 Subject: Ensuring malloced memory is bzero'd. Jeremy (jallison@whistle.com) --- source/namedbname.c | 2 ++ source/namedbresp.c | 2 ++ source/namedbwork.c | 4 +++- 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/source/namedbname.c b/source/namedbname.c index c91541cc815..a45a749f140 100644 --- a/source/namedbname.c +++ b/source/namedbname.c @@ -486,6 +486,8 @@ struct name_record *add_netbios_entry(struct subnet_record *d, return NULL; } + bzero((char *)n->ip_flgs, sizeof(*n->ip_flgs) * n->num_ips); + make_nmb_name(&n->name,name,type,scope); if ((n2 = find_name_search(&found_subnet, &n->name, search, new_only?ipzero:ip))) diff --git a/source/namedbresp.c b/source/namedbresp.c index 98f8ca774bc..86d7eddbd41 100644 --- a/source/namedbresp.c +++ b/source/namedbresp.c @@ -104,6 +104,8 @@ struct response_record *make_response_queue_record(enum state_type state, if (!(n = (struct response_record *)malloc(sizeof(*n)))) return(NULL); + bzero((char *)n, sizeof(*n)); + n->response_id = id; n->state = state; n->fd = fd; diff --git a/source/namedbwork.c b/source/namedbwork.c index 2982ffd3e78..a6260aab467 100644 --- a/source/namedbwork.c +++ b/source/namedbwork.c @@ -84,7 +84,8 @@ static struct work_record *make_workgroup(char *name) work = (struct work_record *)malloc(sizeof(*work)); if (!work) return(NULL); - + bzero((char *)work, sizeof(*work)); + StrnCpy(work->work_group,name,sizeof(work->work_group)-1); work->serverlist = NULL; @@ -92,6 +93,7 @@ static struct work_record *make_workgroup(char *name) SV_TYPE_POTENTIAL_BROWSER : 0 ); work->RunningElection = False; work->ElectionCount = 0; + work->announce_interval = 0; work->needelection = False; work->needannounce = True; work->mst_state = MST_POTENTIAL; -- cgit v1.2.1 From c044da646c613e1e955072937fd7d0ded8b344ec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 19 Sep 1997 00:48:54 +0000 Subject: Added South American consultant. --- docs/textdocs/Support.txt | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/textdocs/Support.txt b/docs/textdocs/Support.txt index 6257872098a..0a5c41b1950 100644 --- a/docs/textdocs/Support.txt +++ b/docs/textdocs/Support.txt @@ -28,7 +28,7 @@ These are currently: Region Number of entries ---------------------------------------------------- AFRICA 2 - AMERICA - CENTRAL & SOUTH 3 + AMERICA - CENTRAL & SOUTH 4 AMERICA - USA 35 ASIA 1 AUSTRALIA & NEW ZEALAND 18 @@ -80,6 +80,25 @@ AMERICA - CENTRAL & SOUTH ========================= +------------------------------------------------------------------------------ +ARGENTINA - SOUTH AMERICA + +Buenos Aires - Argentina + +Guillermo Sansovic +Email: gui@usa.net +Arkham Software +Rivadavia 923 Piso 8 +1002 Buenos Aires +Argentina + +Tel: + 54 1 345-0645 + +At Arkham Software we have been working with Unix systems since 1986. We do +intranets, software development and system integration. Our experience ith +Samba dates from 1995. +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ CHILE - SOUTH AMERICA -- cgit v1.2.1 From c701db19e14d1b53103acbb8f7abe4c8bc2c3614 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 22 Sep 1997 22:09:07 +0000 Subject: Makefile: Added glibc2 fixes for Linux. includes.h: Added glibc2 fixes for Linux. quotas.c: Added OSF1 fix. reply.c: Added fix from Ray Frush to fix zero times for NT clients. Also added old client session keepalives. Jeremy (jallison@whistle.com) --- source/include/includes.h | 8 ++++++++ source/smbd/quotas.c | 20 ++++++++++++++++---- source/smbd/reply.c | 47 ++++++++++++++++++++++++++++++++++++++++------- 3 files changed, 64 insertions(+), 11 deletions(-) diff --git a/source/include/includes.h b/source/include/includes.h index a63f8f8597c..e66ceb2d70c 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -217,6 +217,14 @@ Here come some platform specific sections #ifndef NO_ASMSIGNALH #include #endif +#ifdef GLIBC2 +#define _LINUX_C_LIB_VERSION_MAJOR 6 +#include +#include +#include +#include +#include +#endif #define SIGNAL_CAST (__sighandler_t) #define USE_GETCWD #define USE_SETSID diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index d19d386e273..d4f746c9e36 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -373,22 +373,34 @@ try to get the disk space from disk quotas - OFS1 version BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) { uid_t user_id, euser_id; - int r; + int r, save_errno; struct dqblk D; struct stat S; euser_id = geteuid(); user_id = getuid(); - setreuid(euser_id, euser_id); + setreuid(euser_id, -1); r= quotactl(path,QCMD(Q_GETQUOTA, USRQUOTA),euser_id,(char *) &D); - if (setreuid(user_id, euser_id) == -1) + if (r) + save_errno = errno; + + if (setreuid(user_id, -1) == -1) DEBUG(5,("Unable to reset uid to %d\n", user_id)); *bsize = DEV_BSIZE; if (r) - return(False); + { + if (save_errno == EDQUOT) // disk quota exceeded + { + *dfree = 0; + *dsize = D.dqb_curblocks; + return (True); + } + else + return (False); + } /* Use softlimit to determine disk space, except when it has been exceeded */ diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 228d8ad6692..a15185146da 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -65,19 +65,18 @@ int reply_special(char *inbuf,char *outbuf) smb_setlen(outbuf,0); - switch (msg_type) - { + switch (msg_type) { case 0x81: /* session request */ CVAL(outbuf,0) = 0x82; CVAL(outbuf,3) = 0; - if (name_len(inbuf+4) > 50) - { + if (name_len(inbuf+4) > 50) { DEBUG(0,("Invalid name length in session request\n")); return(0); } name_extract(inbuf,4,name1); name_extract(inbuf,4 + name_len(inbuf + 4),name2); - DEBUG(2,("netbios connect: name1=%s name2=%s\n",name1,name2)); + DEBUG(2,("netbios connect: name1=%s name2=%s\n", + name1,name2)); strcpy(remote_machine,name2); trim_string(remote_machine," "," "); @@ -97,12 +96,26 @@ int reply_special(char *inbuf,char *outbuf) reopen_logs(); break; + + case 0x89: /* session keepalive request + (some old clients produce this?) */ + CVAL(outbuf,0) = 0x85; + CVAL(outbuf,3) = 0; + break; + + case 0x82: /* positive session response */ + case 0x83: /* negative session response */ + case 0x84: /* retarget session response */ + DEBUG(0,("Unexpected session response\n")); + break; + case 0x85: /* session keepalive */ default: return(0); } - DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n",timestring(),msg_type,msg_flags)); + DEBUG(5,("%s init msg_type=0x%x msg_flags=0x%x\n", + timestring(),msg_type,msg_flags)); return(outsize); } @@ -3532,11 +3545,31 @@ int reply_setattrE(char *inbuf,char *outbuf) unix_times.actime = make_unix_date2(inbuf+smb_vwv3); unix_times.modtime = make_unix_date2(inbuf+smb_vwv5); + /* + * Patch from Ray Frush + * Sometimes times are sent as zero - ignore them. + */ + + if ((unix_times.actime == 0) && (unix_times.modtime == 0)) + { + /* Ignore request */ + DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d ignoring zero request - \ +not setting timestamps of 0\n", + timestring(), fnum,cnum,unix_times.actime,unix_times.modtime)); + return(outsize); + } + else if ((unix_times.actime != 0) && (unix_times.modtime == 0)) + { + /* set modify time = to access time if modify time was 0 */ + unix_times.modtime = unix_times.actime; + } + /* Set the date on this file */ if(sys_utime(Files[fnum].name, &unix_times)) return(ERROR(ERRDOS,ERRnoaccess)); - DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d\n",timestring(),fnum,cnum)); + DEBUG(3,("%s reply_setattrE fnum=%d cnum=%d actime=%d modtime=%d\n", + timestring(), fnum,cnum,unix_times.actime,unix_times.modtime)); return(outsize); } -- cgit v1.2.1 From e8dd34b0d3ba704deff696c1683297536a494893 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 26 Sep 1997 12:39:45 +0000 Subject: This commit fixes the security hole due to buffer overflows. The main fix is just a couple of lines long, but I have now also put precautionary checks on a large number of other places in the code where unchecked string copies were being performed. An exploit via one of these copies is unlikely, but is is better to be safe. I also added a routine to log possible exploit attempts using the code that was posted for obtaining root access on a Samba server. --- source/client/clientutil.c | 21 ++++---- source/include/local.h | 2 + source/include/proto.h | 2 + source/lib/system.c | 4 +- source/lib/time.c | 4 +- source/lib/username.c | 4 +- source/lib/util.c | 114 +++++++++++++++++++++++++++++---------- source/libsmb/nmblib.c | 4 +- source/locking/locking.c | 2 +- source/nameannounce.c | 4 +- source/namedbname.c | 8 +-- source/namedbsubnet.c | 4 +- source/nameelect.c | 2 +- source/namelogon.c | 6 +-- source/nmbd/nmbd.c | 22 ++++---- source/nmbsync.c | 4 +- source/param/loadparm.c | 8 +-- source/printing/pcap.c | 4 +- source/printing/printing.c | 36 ++++++------- source/smbd/chgpasswd.c | 12 ++--- source/smbd/dir.c | 2 +- source/smbd/ipc.c | 29 ++++++---- source/smbd/mangle.c | 8 +-- source/smbd/message.c | 14 ++--- source/smbd/pipes.c | 4 +- source/smbd/reply.c | 131 +++++++++++++++++++++++++++------------------ source/smbd/server.c | 36 ++++++------- source/smbd/trans2.c | 28 ++++++---- source/smbd/vt_mode.c | 12 ++--- source/utils/nmblookup.c | 6 +-- 30 files changed, 320 insertions(+), 217 deletions(-) diff --git a/source/client/clientutil.c b/source/client/clientutil.c index b4f0849c5fe..1b59946ff5b 100644 --- a/source/client/clientutil.c +++ b/source/client/clientutil.c @@ -171,7 +171,8 @@ BOOL cli_send_session_request(char *inbuf, char *outbuf) int len = 4; /* send a session request (RFC 8002) */ - strcpy(dest,desthost); + fstrcpy(dest,desthost); + p = strchr(dest,'.'); if (p) *p = 0; @@ -302,11 +303,11 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu outbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); } - strcpy(dev,"A:"); + pstrcpy(dev,"A:"); if (connect_as_printer) - strcpy(dev,"LPT1:"); + pstrcpy(dev,"LPT1:"); if (connect_as_ipc) - strcpy(dev,"IPC"); + pstrcpy(dev,"IPC"); if (start_session && !cli_send_session_request(inbuf,outbuf)) @@ -438,7 +439,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu { fstring pword; int passlen = strlen(pass)+1; - strcpy(pword,pass); + fstrcpy(pword,pass); #ifdef SMB_PASSWD if (doencrypt && *pass) { @@ -451,7 +452,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu #endif /* if in share level security then don't send a password now */ - if (!(sec_mode & 1)) {strcpy(pword, "");passlen=1;} + if (!(sec_mode & 1)) {fstrcpy(pword, "");passlen=1;} /* send a session setup command */ bzero(outbuf,smb_size); @@ -557,7 +558,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu { int passlen = strlen(pass)+1; fstring pword; - strcpy(pword,pass); + fstrcpy(pword,pass); #ifdef SMB_PASSWD if (doencrypt && *pass) { @@ -568,7 +569,7 @@ BOOL cli_send_login(char *inbuf, char *outbuf, BOOL start_session, BOOL use_setu /* if in user level security then don't send a password now */ if ((sec_mode & 1)) { - strcpy(pword, ""); passlen=1; + fstrcpy(pword, ""); passlen=1; } set_message(outbuf,4,2 + strlen(service) + passlen + strlen(dev),True); @@ -817,9 +818,9 @@ BOOL cli_open_sockets(int port) } else { - strcpy(service2,service); + pstrcpy(service2,service); host = strtok(service2,"\\/"); - strcpy(desthost,host); + pstrcpy(desthost,host); } DEBUG(5,("Opening sockets\n")); diff --git a/source/include/local.h b/source/include/local.h index fc589d7ac0d..9548bf74b6b 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -42,6 +42,8 @@ #define WORDMAX 0xFFFF +/* the maximum password length before we declare a likely attack */ +#define MAX_PASSWORD_LENGTH 200 /* separators for lists */ #define LIST_SEP " \t,;:\n\r" diff --git a/source/include/proto.h b/source/include/proto.h index 01afb7cad95..ffa2f251cca 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -976,6 +976,8 @@ void file_unlock(int fd); BOOL is_myname(const char *s); void set_remote_arch(enum remote_arch_types type); enum remote_arch_types get_remote_arch(); +void fstrcpy(char *dest, char *src); +void pstrcpy(char *dest, char *src); /*The following definitions come from vt_mode.c */ diff --git a/source/lib/system.c b/source/lib/system.c index 447a4f88aca..df24691512f 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -311,8 +311,8 @@ int sys_rename(char *from, char *to) int rcode; pstring zfrom, zto; - strcpy (zfrom, dos_to_unix (from, False)); - strcpy (zto, dos_to_unix (to, False)); + pstrcpy (zfrom, dos_to_unix (from, False)); + pstrcpy (zto, dos_to_unix (to, False)); rcode = rename (zfrom, zto); if (errno == EXDEV) diff --git a/source/lib/time.c b/source/lib/time.c index d16552b61e2..4f688d2214a 100644 --- a/source/lib/time.c +++ b/source/lib/time.c @@ -469,12 +469,12 @@ BOOL set_filetime(char *fname,time_t mtime) ****************************************************************************/ char *timestring(void ) { - static char TimeBuf[100]; + static fstring TimeBuf; time_t t = time(NULL); struct tm *tm = LocalTime(&t); #ifdef NO_STRFTIME - strcpy(TimeBuf, asctime(tm)); + fstrcpy(TimeBuf, asctime(tm)); #elif defined(CLIX) || defined(CONVEX) strftime(TimeBuf,100,"%m/%d/%y %I:%M:%S %p",tm); #elif defined(AMPM) diff --git a/source/lib/username.c b/source/lib/username.c index b8d152c83fd..46b8f4cb332 100644 --- a/source/lib/username.c +++ b/source/lib/username.c @@ -62,7 +62,7 @@ void map_username(char *user) if (strequal(user,last_from)) { DEBUG(3,("Mapped user %s to %s\n",user,last_to)); - strcpy(user,last_to); + fstrcpy(user,last_to); return; } @@ -173,7 +173,7 @@ struct passwd *Get_Pwnam(char *user,BOOL allow_change) if (ret) return(ret); if (allow_change) - strcpy(user,user2); + fstrcpy(user,user2); return(NULL); } diff --git a/source/lib/util.c b/source/lib/util.c index 7f922def7e3..0c4999c789c 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -1079,7 +1079,7 @@ void unix_format(char *fname) if (*fname == '/') { - strcpy(namecopy,fname); + pstrcpy(namecopy,fname); strcpy(fname,"."); strcat(fname,namecopy); } @@ -1290,7 +1290,7 @@ void dos_clean_name(char *s) pstring s1; *p = 0; - strcpy(s1,p+3); + pstrcpy(s1,p+3); if ((p=strrchr(s,'\\')) != NULL) *p = 0; @@ -1328,7 +1328,7 @@ void unix_clean_name(char *s) pstring s1; *p = 0; - strcpy(s1,p+3); + pstrcpy(s1,p+3); if ((p=strrchr(s,'/')) != NULL) *p = 0; @@ -1355,7 +1355,7 @@ int ChDir(char *path) DEBUG(3,("chdir to %s\n",path)); res = sys_chdir(path); if (!res) - strcpy(LastDir,path); + pstrcpy(LastDir,path); return(res); } @@ -1515,7 +1515,7 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) /* remove any double slashes */ string_sub(s,"//","/"); - strcpy(basename,s); + pstrcpy(basename,s); p = strrchr(basename,'/'); if (!p) @@ -1585,12 +1585,12 @@ BOOL reduce_name(char *s,char *dir,BOOL widelinks) if (relative) { if (newname[l] == '/') - strcpy(s,newname + l + 1); + pstrcpy(s,newname + l + 1); else - strcpy(s,newname+l); + pstrcpy(s,newname+l); } else - strcpy(s,newname); + pstrcpy(s,newname); } ChDir(wd); @@ -1614,10 +1614,10 @@ static void expand_one(char *Mask,int len) int lfill = (len+1) - strlen(Mask); int l1= (p1 - Mask); pstring tmp; - strcpy(tmp,Mask); + pstrcpy(tmp,Mask); memset(tmp+l1,'?',lfill); - strcpy(tmp + l1 + lfill,Mask + l1 + 1); - strcpy(Mask,tmp); + pstrcpy(tmp + l1 + lfill,Mask + l1 + 1); + pstrcpy(Mask,tmp); } } @@ -1641,20 +1641,20 @@ void expand_mask(char *Mask,BOOL doext) filename_dos(Mask,filepart); - strcpy(mbeg,filepart); + pstrcpy(mbeg,filepart); if ((p1 = strchr(mbeg,'.')) != NULL) { hasdot = True; *p1 = 0; p1++; - strcpy(mext,p1); + pstrcpy(mext,p1); } else { strcpy(mext,""); if (strlen(mbeg) > 8) { - strcpy(mext,mbeg + 8); + pstrcpy(mext,mbeg + 8); mbeg[8] = 0; } } @@ -1672,7 +1672,7 @@ void expand_mask(char *Mask,BOOL doext) if (*mext) expand_one(mext,3); - strcpy(Mask,dirpart); + pstrcpy(Mask,dirpart); if (*dirpart || absolute) strcat(Mask,"\\"); strcat(Mask,mbeg); strcat(Mask,"."); @@ -1773,7 +1773,7 @@ void make_dir_struct(char *buf,char *mask,char *fname,unsigned int size,int mode char *p; pstring mask2; - strcpy(mask2,mask); + pstrcpy(mask2,mask); if ((mode & aDIR) != 0) size = 0; @@ -2421,7 +2421,12 @@ BOOL string_init(char **dest,char *src) } else { - *dest = (char *)malloc(l+1); + (*dest) = (char *)malloc(l+1); + if ((*dest) == NULL) { + DEBUG(0,("Out of memory in string_init\n")); + return False; + } + strcpy(*dest,src); } return(True); @@ -2593,25 +2598,25 @@ BOOL mask_match(char *str, char *regexp, int case_sig,BOOL trans2) DEBUG(5,("mask_match str=<%s> regexp=<%s>, case_sig = %d\n", p2, p1, case_sig)); if (trans2) { - strcpy(ebase,p1); - strcpy(sbase,p2); + fstrcpy(ebase,p1); + fstrcpy(sbase,p2); } else { if ((p=strrchr(p1,'.'))) { *p = 0; - strcpy(ebase,p1); - strcpy(eext,p+1); + fstrcpy(ebase,p1); + fstrcpy(eext,p+1); } else { - strcpy(ebase,p1); + fstrcpy(ebase,p1); eext[0] = 0; } if (!strequal(p2,".") && !strequal(p2,"..") && (p=strrchr(p2,'.'))) { *p = 0; - strcpy(sbase,p2); - strcpy(sext,p+1); + fstrcpy(sbase,p2); + fstrcpy(sext,p+1); } else { - strcpy(sbase,p2); - strcpy(sext,""); + fstrcpy(sbase,p2); + fstrcpy(sext,""); } } @@ -2927,7 +2932,7 @@ BOOL get_myname(char *my_name,struct in_addr *ip) char *p = strchr(hostname,'.'); if (p) *p = 0; - strcpy(my_name,hostname); + fstrcpy(my_name,hostname); } if (ip) @@ -3295,7 +3300,7 @@ char *client_addr(void) return addr_buf; } - strcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); + fstrcpy(addr_buf,(char *)inet_ntoa(sockin->sin_addr)); global_client_addr_done = True; return addr_buf; @@ -3552,7 +3557,7 @@ char *readdirname(void *p) { static pstring buf; - strcpy(buf, dname); + pstrcpy(buf, dname); unix_to_dos(buf, True); dname = buf; } @@ -3907,3 +3912,54 @@ enum remote_arch_types get_remote_arch() { return ra_type; } + + +/******************************************************************* +safe string copy into a fstring +********************************************************************/ +void fstrcpy(char *dest, char *src) +{ + int maxlength = sizeof(fstring) - 1; + if (!dest) { + DEBUG(0,("ERROR: NULL dest in fstrcpy\n")); + return; + } + + if (!src) { + *dest = 0; + return; + } + + while (maxlength-- && *src) + *dest++ = *src++; + *dest = 0; + if (*src) { + DEBUG(0,("ERROR: string overflow by %d in fstrcpy\n", + strlen(src))); + } +} + +/******************************************************************* +safe string copy into a pstring +********************************************************************/ +void pstrcpy(char *dest, char *src) +{ + int maxlength = sizeof(pstring) - 1; + if (!dest) { + DEBUG(0,("ERROR: NULL dest in pstrcpy\n")); + return; + } + + if (!src) { + *dest = 0; + return; + } + + while (maxlength-- && *src) + *dest++ = *src++; + *dest = 0; + if (*src) { + DEBUG(0,("ERROR: string overflow by %d in pstrcpy\n", + strlen(src))); + } +} diff --git a/source/libsmb/nmblib.c b/source/libsmb/nmblib.c index bc967bdacb4..29b54a708bc 100644 --- a/source/libsmb/nmblib.c +++ b/source/libsmb/nmblib.c @@ -616,10 +616,10 @@ static int build_dgram(char *buf,struct packet_struct *p) ******************************************************************/ void make_nmb_name(struct nmb_name *n,char *name,int type,char *this_scope) { - strcpy(n->name,name); + fstrcpy(n->name,name); strupper(n->name); n->name_type = type; - strcpy(n->scope,this_scope); + fstrcpy(n->scope,this_scope); } diff --git a/source/locking/locking.c b/source/locking/locking.c index 760d21a05d8..c2a06cac75c 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -108,7 +108,7 @@ BOOL start_share_mode_mgmt(void) { pstring shmem_file_name; - strcpy(shmem_file_name,lp_lockdir()); + pstrcpy(shmem_file_name,lp_lockdir()); if (!directory_exist(shmem_file_name,NULL)) mkdir(shmem_file_name,0755); trim_string(shmem_file_name,"","/"); diff --git a/source/nameannounce.c b/source/nameannounce.c index 684ef412581..84e3ad3fa77 100644 --- a/source/nameannounce.c +++ b/source/nameannounce.c @@ -174,11 +174,11 @@ void do_announce_host(int command, SSVAL(p,27,BROWSER_ELECTION_VERSION); SSVAL(p,29,BROWSER_CONSTANT); /* browse signature */ - strcpy(p+31,server_comment); + pstrcpy(p+31,server_comment); p += 31; p = skip_string(p,1); - debug_browse_data(outbuf, PTR_DIFF(p,outbuf)); + debug_browse_data(outbuf, PTR_DIFF(p,outbuf)); /* send the announcement */ send_mailslot_reply(False,BROWSE_MAILSLOT,ClientDGRAM,outbuf, diff --git a/source/namedbname.c b/source/namedbname.c index a45a749f140..51571d786a8 100644 --- a/source/namedbname.c +++ b/source/namedbname.c @@ -226,11 +226,11 @@ void dump_names(void) if(lp_wins_support() == False || wins_subnet == 0) return; - strcpy(fname,lp_lockdir()); + fstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,WINS_LIST); - strcpy(fnamenew,fname); + fstrcpy(fnamenew,fname); strcat(fnamenew,"."); f = fopen(fnamenew,"w"); @@ -306,7 +306,7 @@ void load_netbios_names(void) if (!d) return; - strcpy(fname,lp_lockdir()); + fstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,WINS_LIST); @@ -366,7 +366,7 @@ void load_netbios_names(void) nb_flags_str[strlen(nb_flags_str)-1] = '\0'; /* netbios name. # divides the name from the type (hex): netbios#xx */ - strcpy(name,name_str); + pstrcpy(name,name_str); p = strchr(name,'#'); diff --git a/source/namedbsubnet.c b/source/namedbsubnet.c index 6364ebba543..4f0b647996d 100644 --- a/source/namedbsubnet.c +++ b/source/namedbsubnet.c @@ -308,11 +308,11 @@ void write_browse_list(time_t t) dump_names(); dump_workgroups(); - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,SERVER_LIST); - strcpy(fnamenew,fname); + pstrcpy(fnamenew,fname); strcat(fnamenew,"."); f = fopen(fnamenew,"w"); diff --git a/source/nameelect.c b/source/nameelect.c index 4666b22588c..5c156a312ed 100644 --- a/source/nameelect.c +++ b/source/nameelect.c @@ -182,7 +182,7 @@ void send_election(struct subnet_record *d, char *group,uint32 criterion, SIVAL(p,1,criterion); SIVAL(p,5,timeup*1000); /* ms - despite the spec */ p += 13; - strcpy(p,name); + pstrcpy(p,name); strupper(p); p = skip_string(p,1); diff --git a/source/namelogon.c b/source/namelogon.c index 1c118c85418..1f57139d56a 100644 --- a/source/namelogon.c +++ b/source/namelogon.c @@ -74,7 +74,7 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) token = SVAL(tmp,3); reply_code = 0x6; - strcpy(reply_name,myname); + fstrcpy(reply_name,myname); strupper(reply_name); add_slashes = True; DEBUG(3,("Domain login request from %s(%s) user=%s token=%x\n", @@ -87,11 +87,11 @@ void process_logon_packet(struct packet_struct *p,char *buf,int len) logname = skip_string(machine,1); token = SVAL(skip_string(logname,1),0); - strcpy(reply_name,lp_domain_controller()); + fstrcpy(reply_name,lp_domain_controller()); if (!*reply_name) { /* oo! no domain controller. must be us, then */ - strcpy(reply_name,myname); + fstrcpy(reply_name,myname); reply_code = 0xC; } else diff --git a/source/nmbd/nmbd.c b/source/nmbd/nmbd.c index 925f975ffef..3f0279908da 100644 --- a/source/nmbd/nmbd.c +++ b/source/nmbd/nmbd.c @@ -121,7 +121,7 @@ static BOOL dump_core(void) { char *p; pstring dname; - strcpy(dname,debugf); + pstrcpy(dname,debugf); if ((p=strrchr(dname,'/'))) *p=0; strcat(dname,"/corefiles"); mkdir(dname,0700); @@ -188,10 +188,10 @@ BOOL reload_services(BOOL test) if (lp_loaded()) { pstring fname; - strcpy(fname,lp_configfile()); + pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) { - strcpy(servicesf,fname); + pstrcpy(servicesf,fname); test = False; } } @@ -276,7 +276,7 @@ static void load_hosts_file(char *fname) if (strchr(flags,'M')) { source = SELF; - strcpy(myname,name); + pstrcpy(myname,name); } ipaddr = *interpret_addr2(ip); @@ -371,7 +371,7 @@ static BOOL init_structs() pstring nbname; if (! *myname) { - strcpy(myname,myhostname); + fstrcpy(myname,myhostname); p = strchr(myname,'.'); if (p) *p = 0; } @@ -422,7 +422,7 @@ static BOOL init_structs() /* Terminate name list */ my_netbios_names[namecount++]=NULL; - strcpy(local_machine,myname); + fstrcpy(local_machine,myname); trim_string(local_machine," "," "); p = strchr(local_machine,' '); if (p) @@ -501,7 +501,7 @@ static void usage(char *pname) strncpy(pidFile, optarg, sizeof(pidFile)); break; case 's': - strcpy(servicesf,optarg); + pstrcpy(servicesf,optarg); break; case 'N': case 'B': @@ -511,17 +511,17 @@ static void usage(char *pname) DEBUG(0,("Obsolete option '%c' used\n",opt)); break; case 'H': - strcpy(host_file,optarg); + pstrcpy(host_file,optarg); break; case 'n': - strcpy(myname,optarg); + pstrcpy(myname,optarg); strupper(myname); break; case 'l': sprintf(debugf,"%s.nmb",optarg); break; case 'i': - strcpy(scope,optarg); + pstrcpy(scope,optarg); strupper(scope); break; case 'D': @@ -564,7 +564,7 @@ static void usage(char *pname) reload_services(True); - strcpy(myworkgroup, lp_workgroup()); + pstrcpy(myworkgroup, lp_workgroup()); if (strequal(myworkgroup,"*")) { DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n")); diff --git a/source/nmbsync.c b/source/nmbsync.c index f2161f631af..de2f7aa00f1 100644 --- a/source/nmbsync.c +++ b/source/nmbsync.c @@ -82,7 +82,7 @@ static BOOL add_info(struct subnet_record *d, struct work_record *work, int serv SIVAL(p,0,servertype); p += 4; - strcpy(p, work->work_group); + pstrcpy(p, work->work_group); p = skip_string(p,1); if (cli_call_api(PTR_DIFF(p,param),0, 8,BUFFER_SIZE - SAFETY_MARGIN, @@ -162,7 +162,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work, name, work->work_group, inet_ntoa(ip))); strcpy(workgroup,work->work_group); - strcpy(desthost,name); + fstrcpy(desthost,name); dest_ip = ip; if (zero_ip(dest_ip)) return; diff --git a/source/param/loadparm.c b/source/param/loadparm.c index ad9bf83886d..510a661dc39 100644 --- a/source/param/loadparm.c +++ b/source/param/loadparm.c @@ -1382,7 +1382,7 @@ static void add_to_file_list(char *fname) { pstring n2; - strcpy(n2,fname); + pstrcpy(n2,fname); standard_sub_basic(n2); f->modtime = file_modtime(n2); } @@ -1402,7 +1402,7 @@ BOOL lp_file_list_changed(void) pstring n2; time_t mod_time; - strcpy(n2,f->name); + pstrcpy(n2,f->name); standard_sub_basic(n2); DEBUG(6,("file %s -> %s last mod_time: %s\n", @@ -1532,7 +1532,7 @@ handle the include operation static BOOL handle_include(char *pszParmValue,char **ptr) { pstring fname; - strcpy(fname,pszParmValue); + pstrcpy(fname,pszParmValue); add_to_file_list(fname); @@ -2025,7 +2025,7 @@ BOOL lp_load(char *pszFname,BOOL global_only) init_globals(); - strcpy(n2,pszFname); + pstrcpy(n2,pszFname); standard_sub_basic(n2); /* We get sections first, so have to start 'behind' to make up */ diff --git a/source/printing/pcap.c b/source/printing/pcap.c index 549ebcd70df..65195ab1af6 100644 --- a/source/printing/pcap.c +++ b/source/printing/pcap.c @@ -358,8 +358,8 @@ void pcap_printer_fn(void (*fn)()) if (strlen(p) <= 8 && strlen(p)>strlen(name) && !has_punctuation) { - if (!*comment) strcpy(comment,name); - strcpy(name,p); + if (!*comment) pstrcpy(comment,name); + pstrcpy(name,p); continue; } diff --git a/source/printing/printing.c b/source/printing/printing.c index c83d2169891..51fd3a992eb 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -85,7 +85,7 @@ static char *build_print_command(int cnum, char *command, char *syscmd, char *fi strcat(filename,filename1); } else - strcpy(filename,filename1); + pstrcpy(filename,filename1); string_sub(syscmd, "%s", filename); } @@ -258,7 +258,7 @@ static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first) if (p) { strcpy(tmp,p+1); - strcpy(tok[FILETOK],tmp); + fstrcpy(tok[FILETOK],tmp); } } @@ -404,8 +404,8 @@ A long spool-path will just waste significant chars of the file name. char *p = strrchr(tok[LPRNG_FILETOK],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[LPRNG_FILETOK],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[LPRNG_FILETOK],tmp); } } @@ -472,8 +472,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[2],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[2],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[2],tmp); } } @@ -506,8 +506,8 @@ static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[4],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[4],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[4],tmp); } } @@ -666,8 +666,8 @@ static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first) if ((p=strchr(tok[2],'!'))) { string tmp; - strcpy(tmp,p+1); - strcpy(tok[2],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[2],tmp); } @@ -731,8 +731,8 @@ static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[6],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[6],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[6],tmp); } } @@ -795,8 +795,8 @@ static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first) char *p = strrchr(tok[6],'/'); if (p) { - strcpy(tmp,p+1); - strcpy(tok[6],tmp); + fstrcpy(tmp,p+1); + fstrcpy(tok[6],tmp); } } @@ -863,7 +863,7 @@ static BOOL parse_lpq_entry(int snum,char *line, /* change guest entries to the current logged in user to make them appear deletable to windows */ if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum))) - strcpy(buf->user,sesssetup_user); + pstrcpy(buf->user,sesssetup_user); } #endif @@ -940,7 +940,7 @@ int get_printqueue(int snum,int cnum,print_queue_struct **queue, return(0); } - strcpy(syscmd,lpq_command); + pstrcpy(syscmd,lpq_command); string_sub(syscmd,"%p",printername); standard_sub(cnum,syscmd); @@ -1031,7 +1031,7 @@ void del_printqueue(int cnum,int snum,int jobid) sprintf(jobstr,"%d",jobid); - strcpy(syscmd,lprm_command); + pstrcpy(syscmd,lprm_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); @@ -1069,7 +1069,7 @@ void status_printjob(int cnum,int snum,int jobid,int status) sprintf(jobstr,"%d",jobid); - strcpy(syscmd,lpstatus_command); + pstrcpy(syscmd,lpstatus_command); string_sub(syscmd,"%p",printername); string_sub(syscmd,"%j",jobstr); standard_sub(cnum,syscmd); diff --git a/source/smbd/chgpasswd.c b/source/smbd/chgpasswd.c index 6063f2aac8a..bed81138b24 100644 --- a/source/smbd/chgpasswd.c +++ b/source/smbd/chgpasswd.c @@ -212,8 +212,8 @@ static int expect(int master,char *expected,char *buf) { pstring s1,s2; - strcpy(s1,buf); - strcpy(s2,expected); + pstrcpy(s1,buf); + pstrcpy(s2,expected); if (do_match(s1, s2, False)) return(True); } @@ -364,11 +364,11 @@ BOOL chgpasswd(char *name,char *oldpass,char *newpass) } #if (defined(PASSWD_PROGRAM) && defined(PASSWD_CHAT)) - strcpy(passwordprogram,PASSWD_PROGRAM); - strcpy(chatsequence,PASSWD_CHAT); + pstrcpy(passwordprogram,PASSWD_PROGRAM); + pstrcpy(chatsequence,PASSWD_CHAT); #else - strcpy(passwordprogram,lp_passwd_program()); - strcpy(chatsequence,lp_passwd_chat()); + pstrcpy(passwordprogram,lp_passwd_program()); + pstrcpy(chatsequence,lp_passwd_chat()); #endif if (!*chatsequence) { diff --git a/source/smbd/dir.c b/source/smbd/dir.c index 06ee6ae8ed7..567bc14424e 100644 --- a/source/smbd/dir.c +++ b/source/smbd/dir.c @@ -461,7 +461,7 @@ BOOL get_dir_entry(int cnum,char *mask,int dirtype,char *fname,int *size,int *mo matched = False; - strcpy(filename,dname); + pstrcpy(filename,dname); if ((strcmp(filename,mask) == 0) || (name_map_mangle(filename,True,SNUM(cnum)) && diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 55e293d7ffd..9aaf03e6c4f 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -774,7 +774,7 @@ static int get_server_info(uint32 servertype, pstring line; BOOL local_list_only; - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); trim_string(fname,NULL,"/"); strcat(fname,"/"); strcat(fname,SERVER_LIST); @@ -1363,7 +1363,7 @@ static BOOL api_SetUserPassword(int cnum,uint16 vuid, char *param,char *data, fstring user; fstring pass1,pass2; - strcpy(user,p); + fstrcpy(user,p); p = skip_string(p,1); @@ -1698,14 +1698,14 @@ static BOOL api_RNetServerGetInfo(int cnum,uint16 vuid, char *param,char *data, pstring comment; uint32 servertype= lp_default_server_announce(); - strcpy(comment,lp_serverstring()); + pstrcpy(comment,lp_serverstring()); if ((count=get_server_info(SV_TYPE_ALL,&servers,myworkgroup))>0) { for (i=0;i 0) { @@ -2043,9 +2043,9 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, strcpy(p2,"UserComment"); p2 = skip_string(p2,1); - /* EEK! the cifsrap.txt doesn't have this in!!!! */ + /* EEK! the cifsrap.txt doesn't have this in!!!! */ SIVAL(p,usri11_full_name,PTR_DIFF(p2,p)); /* full name */ - strcpy(p2,vuser->real_name); /* simeon */ + strcpy(p2,vuser->real_name); /* simeon */ p2 = skip_string(p2,1); } @@ -2062,7 +2062,7 @@ static BOOL api_RNetUserGetInfo(int cnum,uint16 vuid, char *param,char *data, else { #if (defined(NETGROUP) && defined(AUTOMOUNT)) - strcpy(p2, vuser->home_share); + strcpy(p2, vuser->home_share); #else strcpy(p2,"\\\\%L\\%U"); #endif @@ -2461,7 +2461,8 @@ static void fill_printdest_info(int cnum, int snum, int uLevel, struct pack_desc* desc) { char buf[100]; - strcpy(buf,SERVICE(snum)); + strncpy(buf,SERVICE(snum),sizeof(buf)-1); + buf[sizeof(buf)-1] = 0; strupper(buf); if (uLevel <= 1) { PACKS(desc,"B9",buf); /* szName */ @@ -3018,7 +3019,11 @@ int reply_trans(char *inbuf,char *outbuf) int dsoff = SVAL(inbuf,smb_vwv12); int suwcnt = CVAL(inbuf,smb_vwv13); - StrnCpy(name,smb_buf(inbuf),sizeof(name)-1); + fstrcpy(name,smb_buf(inbuf)); + + if (dscnt > tdscnt || pscnt > tpscnt) { + exit_server("invalid trans parameters\n"); + } if (tdscnt) { @@ -3080,6 +3085,10 @@ int reply_trans(char *inbuf,char *outbuf) pscnt += pcnt; dscnt += dcnt; + if (dscnt > tdscnt || pscnt > tpscnt) { + exit_server("invalid trans parameters\n"); + } + if (pcnt) memcpy(params+pdisp,smb_base(inbuf)+poff,pcnt); if (dcnt) diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c index a08402a85ea..a964f4a5c73 100644 --- a/source/smbd/mangle.c +++ b/source/smbd/mangle.c @@ -269,7 +269,7 @@ BOOL check_mangled_stack(char *s) } if (check_extension && !strchr(mangled_stack[i],'.')) { - strcpy(tmpname,mangled_stack[i]); + pstrcpy(tmpname,mangled_stack[i]); strcat(tmpname,extension); mangle_name_83(tmpname); if (strequal(tmpname,s)) @@ -303,7 +303,7 @@ static char *map_filename(char *s, /* This is null terminated */ pstring pat; StrnCpy(pat, pattern, len); /* Get pattern into a proper string! */ - strcpy(matching_bit,""); /* Match but no star gets this. */ + pstrcpy(matching_bit,""); /* Match but no star gets this. */ pp = pat; /* Initialise the pointers. */ sp = s; if ((len == 1) && (*pattern == '*')) { @@ -442,7 +442,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap) continue; /* Always check for the end. */ } if (*end == '*') { - strcpy(np, match_string); + pstrcpy(np, match_string); np += strlen(match_string); end++; /* Skip the '*' */ while ((*end) /* Not the end of string. */ @@ -456,7 +456,7 @@ static void do_fwd_mangled_map(char *s, char *MangledMap) } *np++ = '\0'; /* NULL terminate it. */ DEBUG(5,("End of second in pair '%s'\n", end)); - strcpy(s, new_string); /* Substitute with the new name. */ + pstrcpy(s, new_string); /* Substitute with the new name. */ DEBUG(5,("s is now '%s'\n", s)); } start = end; /* Skip a bit which cannot be wanted */ diff --git a/source/smbd/message.c b/source/smbd/message.c index 93a2d9d850a..64253932abb 100644 --- a/source/smbd/message.c +++ b/source/smbd/message.c @@ -54,7 +54,7 @@ static void msg_deliver(void) /* put it in a temporary file */ sprintf(s,"%s/msg.XXXXXX",tmpdir()); - strcpy(name,(char *)mktemp(s)); + fstrcpy(name,(char *)mktemp(s)); fd = open(name,O_WRONLY|O_CREAT|O_TRUNC|O_EXCL,0600); if (fd == -1) { @@ -74,7 +74,7 @@ static void msg_deliver(void) /* run the command */ if (*lp_msg_command()) { - strcpy(s,lp_msg_command()); + pstrcpy(s,lp_msg_command()); string_sub(s,"%s",name); string_sub(s,"%f",msgfrom); string_sub(s,"%t",msgto); @@ -108,8 +108,8 @@ int reply_sends(char *inbuf,char *outbuf) dest = skip_string(orig,1)+1; msg = skip_string(dest,1)+1; - strcpy(msgfrom,orig); - strcpy(msgto,dest); + fstrcpy(msgfrom,orig); + fstrcpy(msgto,dest); len = SVAL(msg,0); len = MIN(len,1600-msgpos); @@ -143,10 +143,10 @@ int reply_sendstrt(char *inbuf,char *outbuf) orig = smb_buf(inbuf)+1; dest = skip_string(orig,1)+1; - strcpy(msgfrom,orig); - strcpy(msgto,dest); + fstrcpy(msgfrom,orig); + fstrcpy(msgto,dest); - DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),orig,dest)); + DEBUG(3,("%s SMBsendstrt (from %s to %s)\n",timestring(),msgfrom,msgto)); return(outsize); } diff --git a/source/smbd/pipes.c b/source/smbd/pipes.c index afab7e1d911..feb8d91a5b0 100644 --- a/source/smbd/pipes.c +++ b/source/smbd/pipes.c @@ -87,7 +87,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) BOOL bad_path = False; /* XXXX we need to handle passed times, sattr and flags */ - strcpy(fname,smb_buf(inbuf)); + pstrcpy(fname,smb_buf(inbuf)); /* If the name doesn't start \PIPE\ then this is directed */ /* at a mailslot or something we really, really don't understand, */ @@ -98,7 +98,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) DEBUG(4,("Opening pipe %s.\n", fname)); /* Strip \PIPE\ off the name. */ - strcpy(fname,smb_buf(inbuf) + PIPELEN); + pstrcpy(fname,smb_buf(inbuf) + PIPELEN); /* See if it is one we want to handle. */ for( i = 0; known_pipes[i] ; i++ ) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index a15185146da..4235e7725e9 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -48,6 +48,18 @@ a packet to ensure chaining works correctly */ #define GETFNUM(buf,where) (chain_fnum!= -1?chain_fnum:SVAL(buf,where)) +/**************************************************************************** +report a possible attack via the password buffer overflow bug +****************************************************************************/ +static void overflow_attack(int len) +{ + DEBUG(0,("ERROR: Invalid password length %d\n", len)); + DEBUG(0,("you're machine may be under attack by a user exploiting an old bug\n")); + DEBUG(0,("Attack was from IP=%s\n", client_addr())); + exit_server("possible attack"); +} + + /**************************************************************************** reply to an special message ****************************************************************************/ @@ -69,22 +81,22 @@ int reply_special(char *inbuf,char *outbuf) case 0x81: /* session request */ CVAL(outbuf,0) = 0x82; CVAL(outbuf,3) = 0; - if (name_len(inbuf+4) > 50) { - DEBUG(0,("Invalid name length in session request\n")); - return(0); - } + if (name_len(inbuf+4) > 50 || name_len(inbuf+4 + name_len(inbuf + 4)) > 50) { + DEBUG(0,("Invalid name length in session request\n")); + return(0); + } name_extract(inbuf,4,name1); name_extract(inbuf,4 + name_len(inbuf + 4),name2); DEBUG(2,("netbios connect: name1=%s name2=%s\n", name1,name2)); - strcpy(remote_machine,name2); + fstrcpy(remote_machine,name2); trim_string(remote_machine," "," "); p = strchr(remote_machine,' '); strlower(remote_machine); if (p) *p = 0; - strcpy(local_machine,name1); + fstrcpy(local_machine,name1); trim_string(local_machine," "," "); p = strchr(local_machine,' '); strlower(local_machine); @@ -160,25 +172,25 @@ static void parse_connect(char *p,char *service,char *user, p2 = strrchr(p,'\\'); if (p2 == NULL) - strcpy(service,p); + fstrcpy(service,p); else - strcpy(service,p2+1); + fstrcpy(service,p2+1); p += strlen(p) + 2; - strcpy(password,p); + fstrcpy(password,p); *pwlen = strlen(password); p += strlen(p) + 2; - strcpy(dev,p); + fstrcpy(dev,p); *user = 0; p = strchr(service,'%'); if (p != NULL) { *p = 0; - strcpy(user,p+1); + fstrcpy(user,p+1); } } @@ -238,6 +250,10 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* we might have to close an old one */ if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0) close_cnum(SVAL(inbuf,smb_tid),vuid); + + if (passlen > MAX_PASSWORD_LENGTH) { + overflow_attack(passlen); + } { char *path; @@ -252,18 +268,17 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) passlen = strlen(password); } - DEBUG(4,("parsing net-path %s, passlen=%d\n",path,passlen)); - strcpy(service,path+2); + fstrcpy(service,path+2); p = strchr(service,'\\'); if (!p) return(ERROR(ERRSRV,ERRinvnetname)); *p = 0; - strcpy(service,p+1); + fstrcpy(service,p+1); p = strchr(service,'%'); if (p) { *p++ = 0; - strcpy(user,p); + fstrcpy(user,p); } StrnCpy(devicename,path + strlen(path) + 1,6); DEBUG(4,("Got device type %s\n",devicename)); @@ -372,11 +387,15 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (Protocol < PROTOCOL_NT1) { smb_apasslen = SVAL(inbuf,smb_vwv7); + if (smb_apasslen > MAX_PASSWORD_LENGTH) + overflow_attack(smb_apasslen); + memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); - StrnCpy(user,smb_buf(inbuf)+smb_apasslen,sizeof(user)-1); + pstrcpy(user,smb_buf(inbuf)+smb_apasslen); - if (lp_security() != SEC_SERVER && !doencrypt) - smb_apasslen = strlen(smb_apasswd); + if (lp_security() != SEC_SERVER && !doencrypt) { + smb_apasslen = strlen(smb_apasswd); + } } else { uint16 passlen1 = SVAL(inbuf,smb_vwv7); uint16 passlen2 = SVAL(inbuf,smb_vwv8); @@ -401,6 +420,13 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen1 != 24 && passlen2 != 24) doencrypt = False; + if (passlen1 > MAX_PASSWORD_LENGTH) { + overflow_attack(passlen1); + } + + passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH); + passlen2 = MIN(passlen2, MAX_PASSWORD_LENGTH); + if(doencrypt) { /* Save the lanman2 password and the NT md4 password. */ smb_apasslen = passlen1; @@ -438,7 +464,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) } p += passlen1 + passlen2; - strcpy(user,p); p = skip_string(p,1); + fstrcpy(user,p); p = skip_string(p,1); DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s]\n", p,skip_string(p,1),skip_string(p,2))); } @@ -591,7 +617,7 @@ int reply_chkpth(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(name,smb_buf(inbuf) + 1); + pstrcpy(name,smb_buf(inbuf) + 1); unix_convert(name,cnum,0,&bad_path); mode = SVAL(inbuf,smb_vwv0); @@ -639,7 +665,7 @@ int reply_getatr(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(fname,smb_buf(inbuf) + 1); + pstrcpy(fname,smb_buf(inbuf) + 1); unix_convert(fname,cnum,0,&bad_path); /* dos smetimes asks for a stat of "" - it returns a "hidden directory" @@ -714,7 +740,7 @@ int reply_setatr(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(fname,smb_buf(inbuf) + 1); + pstrcpy(fname,smb_buf(inbuf) + 1); unix_convert(fname,cnum,0,&bad_path); mode = SVAL(inbuf,smb_vwv0); @@ -825,8 +851,8 @@ int reply_search(char *inbuf,char *outbuf) { pstring dir2; - strcpy(directory,smb_buf(inbuf)+1); - strcpy(dir2,smb_buf(inbuf)+1); + pstrcpy(directory,smb_buf(inbuf)+1); + pstrcpy(dir2,smb_buf(inbuf)+1); unix_convert(directory,cnum,0,&bad_path); unix_format(dir2); @@ -842,7 +868,7 @@ int reply_search(char *inbuf,char *outbuf) else { *p = 0; - strcpy(mask,p+1); + pstrcpy(mask,p+1); } p = strrchr(directory,'/'); @@ -876,7 +902,7 @@ int reply_search(char *inbuf,char *outbuf) if ((p = strrchr(mask,' '))) { fstring ext; - strcpy(ext,p+1); + fstrcpy(ext,p+1); *p = 0; trim_string(mask,NULL," "); strcat(mask,"."); @@ -898,7 +924,7 @@ int reply_search(char *inbuf,char *outbuf) if (!strchr(mask,'.') && strlen(mask)>8) { fstring tmp; - strcpy(tmp,&mask[8]); + fstrcpy(tmp,&mask[8]); mask[8] = '.'; mask[9] = 0; strcat(mask,tmp); @@ -1078,7 +1104,7 @@ int reply_open(char *inbuf,char *outbuf) share_mode = SVAL(inbuf,smb_vwv0); - strcpy(fname,smb_buf(inbuf)+1); + pstrcpy(fname,smb_buf(inbuf)+1); unix_convert(fname,cnum,0,&bad_path); fnum = find_free_file(); @@ -1168,7 +1194,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) /* XXXX we need to handle passed times, sattr and flags */ - strcpy(fname,smb_buf(inbuf)); + pstrcpy(fname,smb_buf(inbuf)); unix_convert(fname,cnum,0,&bad_path); fnum = find_free_file(); @@ -1281,7 +1307,7 @@ int reply_mknew(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); - strcpy(fname,smb_buf(inbuf)+1); + pstrcpy(fname,smb_buf(inbuf)+1); unix_convert(fname,cnum,0,&bad_path); if (createmode & aVOLID) @@ -1359,7 +1385,8 @@ int reply_ctemp(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); createmode = SVAL(inbuf,smb_vwv0); - sprintf(fname,"%s/TMXXXXXX",smb_buf(inbuf)+1); + pstrcpy(fname,smb_buf(inbuf)+1); + strcat(fname,"/TMXXXXXX"); unix_convert(fname,cnum,0,&bad_path); unixmode = unix_mode(cnum,createmode); @@ -1455,7 +1482,7 @@ int reply_unlink(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); dirtype = SVAL(inbuf,smb_vwv0); - strcpy(name,smb_buf(inbuf) + 1); + pstrcpy(name,smb_buf(inbuf) + 1); DEBUG(3,("reply_unlink : %s\n",name)); @@ -1503,7 +1530,7 @@ int reply_unlink(char *inbuf,char *outbuf) while ((dname = ReadDirName(dirptr))) { pstring fname; - strcpy(fname,dname); + pstrcpy(fname,dname); if(!mask_match(fname, mask, case_sensitive, False)) continue; @@ -2381,7 +2408,7 @@ int reply_printopen(char *inbuf,char *outbuf) { pstring s; char *p; - StrnCpy(s,smb_buf(inbuf)+1,sizeof(pstring)-1); + pstrcpy(s,smb_buf(inbuf)+1); p = s; while (*p) { @@ -2583,7 +2610,7 @@ int reply_mkdir(char *inbuf,char *outbuf) int outsize,ret= -1; BOOL bad_path = False; - strcpy(directory,smb_buf(inbuf) + 1); + pstrcpy(directory,smb_buf(inbuf) + 1); cnum = SVAL(inbuf,smb_tid); unix_convert(directory,cnum,0,&bad_path); @@ -2620,7 +2647,7 @@ int reply_rmdir(char *inbuf,char *outbuf) BOOL bad_path = False; cnum = SVAL(inbuf,smb_tid); - strcpy(directory,smb_buf(inbuf) + 1); + pstrcpy(directory,smb_buf(inbuf) + 1); unix_convert(directory,cnum,0,&bad_path); if (check_name(directory,cnum)) @@ -2668,7 +2695,7 @@ int reply_rmdir(char *inbuf,char *outbuf) errno = ENOMEM; break; } - strcpy(fullname, directory); + pstrcpy(fullname, directory); strcat(fullname, "/"); strcat(fullname, dname); @@ -2730,21 +2757,21 @@ static BOOL resolve_wildcards(char *name1,char *name2) if (!name1 || !name2) return(False); - strcpy(root1,name1); - strcpy(root2,name2); + fstrcpy(root1,name1); + fstrcpy(root2,name2); p = strrchr(root1,'.'); if (p) { *p = 0; - strcpy(ext1,p+1); + fstrcpy(ext1,p+1); } else { - strcpy(ext1,""); + fstrcpy(ext1,""); } p = strrchr(root2,'.'); if (p) { *p = 0; - strcpy(ext2,p+1); + fstrcpy(ext2,p+1); } else { - strcpy(ext2,""); + fstrcpy(ext2,""); } p = root1; @@ -2818,8 +2845,8 @@ int reply_mv(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(name,smb_buf(inbuf) + 1); - strcpy(newname,smb_buf(inbuf) + 3 + strlen(name)); + pstrcpy(name,smb_buf(inbuf) + 1); + pstrcpy(newname,smb_buf(inbuf) + 3 + strlen(name)); DEBUG(3,("reply_mv : %s -> %s\n",name,newname)); @@ -2933,14 +2960,14 @@ int reply_mv(char *inbuf,char *outbuf) while ((dname = ReadDirName(dirptr))) { pstring fname; - strcpy(fname,dname); + pstrcpy(fname,dname); if(!mask_match(fname, mask, case_sensitive, False)) continue; error = ERRnoaccess; sprintf(fname,"%s/%s",directory,dname); if (!can_rename(fname,cnum)) continue; - strcpy(destname,newname); + pstrcpy(destname,newname); if (!resolve_wildcards(fname,destname)) continue; @@ -2986,7 +3013,7 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, int fnum1,fnum2; pstring dest; - strcpy(dest,dest1); + pstrcpy(dest,dest1); if (target_is_directory) { char *p = strrchr(src,'/'); if (p) @@ -3063,8 +3090,8 @@ int reply_copy(char *inbuf,char *outbuf) cnum = SVAL(inbuf,smb_tid); - strcpy(name,smb_buf(inbuf)); - strcpy(newname,smb_buf(inbuf) + 1 + strlen(name)); + pstrcpy(name,smb_buf(inbuf)); + pstrcpy(newname,smb_buf(inbuf) + 1 + strlen(name)); DEBUG(3,("reply_copy : %s -> %s\n",name,newname)); @@ -3133,7 +3160,7 @@ int reply_copy(char *inbuf,char *outbuf) while ((dname = ReadDirName(dirptr))) { pstring fname; - strcpy(fname,dname); + pstrcpy(fname,dname); if(!mask_match(fname, mask, case_sensitive, False)) continue; @@ -3187,7 +3214,7 @@ int reply_setdir(char *inbuf,char *outbuf) if (!CAN_SETDIR(snum)) return(ERROR(ERRDOS,ERRnoaccess)); - strcpy(newdir,smb_buf(inbuf) + 1); + pstrcpy(newdir,smb_buf(inbuf) + 1); strlower(newdir); if (strlen(newdir) == 0) diff --git a/source/smbd/server.c b/source/smbd/server.c index d4407269f0b..2bc0e023158 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -393,7 +393,7 @@ static BOOL scan_directory(char *path, char *name,int cnum,BOOL docache) (strequal(dname,".") || strequal(dname,".."))) continue; - strcpy(name2,dname); + pstrcpy(name2,dname); if (!name_map_mangle(name2,False,SNUM(cnum))) continue; if ((mangled && mangled_equal(name,name2)) @@ -539,7 +539,7 @@ BOOL unix_convert(char *name,int cnum,pstring saved_last_component, BOOL *bad_pa /* remember the rest of the pathname so it can be restored later */ - if (end) strcpy(rest,end+1); + if (end) pstrcpy(rest,end+1); /* try to find this part of the path in the directory */ if (strchr(start,'?') || strchr(start,'*') || @@ -1051,7 +1051,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct Files[fnum].fd_ptr = 0; errno = EPERM; - strcpy(fname,fname1); + pstrcpy(fname,fname1); /* check permissions */ if ((flags != O_RDONLY) && !CAN_WRITE(cnum) && !Connections[cnum].printer) @@ -1180,7 +1180,7 @@ static void open_file(int fnum,int cnum,char *fname1,int flags,int mode, struct pstring dname; int dum1,dum2,dum3; char *p; - strcpy(dname,fname); + pstrcpy(dname,fname); p = strrchr(dname,'/'); if (p) *p = 0; if (sys_disk_free(dname,&dum1,&dum2,&dum3) < @@ -1315,10 +1315,10 @@ static void check_magic(int fnum,int cnum) int ret; pstring magic_output; pstring fname; - strcpy(fname,Files[fnum].name); + pstrcpy(fname,Files[fnum].name); if (*lp_magicoutput(SNUM(cnum))) - strcpy(magic_output,lp_magicoutput(SNUM(cnum))); + pstrcpy(magic_output,lp_magicoutput(SNUM(cnum))); else sprintf(magic_output,"%s.out",fname); @@ -2280,10 +2280,10 @@ BOOL reload_services(BOOL test) if (lp_loaded()) { pstring fname; - strcpy(fname,lp_configfile()); + pstrcpy(fname,lp_configfile()); if (file_exist(fname,NULL) && !strcsequal(fname,servicesf)) { - strcpy(servicesf,fname); + pstrcpy(servicesf,fname); test = False; } } @@ -2576,13 +2576,13 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de { struct passwd *pass2; fstring fuser; - strcpy(fuser,lp_force_user(snum)); + fstrcpy(fuser,lp_force_user(snum)); pass2 = (struct passwd *)Get_Pwnam(fuser,True); if (pass2) { pcon->uid = pass2->pw_uid; string_set(&pcon->user,fuser); - strcpy(user,fuser); + fstrcpy(user,fuser); pcon->force_user = True; DEBUG(3,("Forced user %s\n",fuser)); } @@ -2592,7 +2592,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de { pstring s; - strcpy(s,lp_pathname(snum)); + pstrcpy(s,lp_pathname(snum)); standard_sub(cnum,s); string_set(&pcon->connectpath,s); DEBUG(3,("Connect path is %s\n",s)); @@ -2628,7 +2628,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de if (*lp_rootpreexec(SNUM(cnum))) { pstring cmd; - strcpy(cmd,lp_rootpreexec(SNUM(cnum))); + pstrcpy(cmd,lp_rootpreexec(SNUM(cnum))); standard_sub(cnum,cmd); DEBUG(5,("cmd=%s\n",cmd)); smbrun(cmd,NULL,False); @@ -2668,7 +2668,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de /* resolve any soft links early */ { pstring s; - strcpy(s,pcon->connectpath); + pstrcpy(s,pcon->connectpath); GetWd(s); string_set(&pcon->connectpath,s); ChDir(pcon->connectpath); @@ -2682,7 +2682,7 @@ int make_connection(char *service,char *user,char *password, int pwlen, char *de if (*lp_preexec(SNUM(cnum))) { pstring cmd; - strcpy(cmd,lp_preexec(SNUM(cnum))); + pstrcpy(cmd,lp_preexec(SNUM(cnum))); standard_sub(cnum,cmd); smbrun(cmd,NULL,False); } @@ -3153,7 +3153,7 @@ static int reply_negprot(char *inbuf,char *outbuf) SSVAL(outbuf,smb_vwv0,choice); if(choice != -1) { extern fstring remote_proto; - strcpy(remote_proto,supported_protocols[protocol].short_name); + fstrcpy(remote_proto,supported_protocols[protocol].short_name); reload_services(True); outsize = supported_protocols[protocol].proto_reply_fn(outbuf); DEBUG(3,("Selected protocol %s\n",supported_protocols[protocol].proto_name)); @@ -3272,7 +3272,7 @@ BOOL yield_connection(int cnum,char *name,int max_connections) bzero(&crec,sizeof(crec)); - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); standard_sub(cnum,fname); trim_string(fname,"","/"); @@ -3344,7 +3344,7 @@ BOOL claim_connection(int cnum,char *name,int max_connections,BOOL Clear) DEBUG(5,("trying claim %s %s %d\n",lp_lockdir(),name,max_connections)); - strcpy(fname,lp_lockdir()); + pstrcpy(fname,lp_lockdir()); standard_sub(cnum,fname); trim_string(fname,"","/"); @@ -3440,7 +3440,7 @@ static BOOL dump_core(void) { char *p; pstring dname; - strcpy(dname,debugf); + pstrcpy(dname,debugf); if ((p=strrchr(dname,'/'))) *p=0; strcat(dname,"/corefiles"); mkdir(dname,0700); diff --git a/source/smbd/trans2.c b/source/smbd/trans2.c index 19c1158658c..ecc8f5dbec7 100644 --- a/source/smbd/trans2.c +++ b/source/smbd/trans2.c @@ -306,10 +306,10 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l if(p[1] == '\0') strcpy(mask,"*.*"); else - strcpy(mask, p+1); + pstrcpy(mask, p+1); } else - strcpy(mask, path_mask); + pstrcpy(mask, path_mask); while (!found) { @@ -327,7 +327,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l matched = False; - strcpy(fname,dname); + pstrcpy(fname,dname); if(mask_match(fname, mask, case_sensitive, True)) { @@ -338,7 +338,7 @@ static int get_lanman2_dir_entry(int cnum,char *path_mask,int dirtype,int info_l if (isrootdir && isdots) continue; - strcpy(pathreal,Connections[cnum].dirpath); + pstrcpy(pathreal,Connections[cnum].dirpath); if(needslash) strcat(pathreal,"/"); strcat(pathreal,dname); @@ -595,7 +595,7 @@ static int call_trans2findfirst(char *inbuf, char *outbuf, int bufsize, int cnum return(ERROR(ERRDOS,ERRunknownlevel)); } - strcpy(directory, params + 12); /* Complete directory path with + pstrcpy(directory, params + 12); /* Complete directory path with wildcard mask appended */ DEBUG(5,("path=%s\n",directory)); @@ -1057,7 +1057,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, /* qpathinfo */ info_level = SVAL(params,0); fname = &fname1[0]; - strcpy(fname,¶ms[6]); + pstrcpy(fname,¶ms[6]); unix_convert(fname,cnum,0,&bad_path); if (!check_name(fname,cnum) || sys_stat(fname,&sbuf)) { DEBUG(3,("fileinfo of %s failed (%s)\n",fname,strerror(errno))); @@ -1163,7 +1163,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, case SMB_QUERY_FILE_ALT_NAME_INFO: data_size = 4 + l; SIVAL(pdata,0,l); - strcpy(pdata+4,fname); + pstrcpy(pdata+4,fname); break; case SMB_QUERY_FILE_ALLOCATION_INFO: case SMB_QUERY_FILE_END_OF_FILEINFO: @@ -1197,7 +1197,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, pdata += 4; pdata += 4; /* alignment */ SIVAL(pdata,0,l); - strcpy(pdata+4,fname); + pstrcpy(pdata+4,fname); pdata += 4 + l; data_size = PTR_DIFF(pdata,(*ppdata)); break; @@ -1208,7 +1208,7 @@ static int call_trans2qfilepathinfo(char *inbuf, char *outbuf, int length, SIVAL(pdata,4,size); SIVAL(pdata,12,size); SIVAL(pdata,20,l); - strcpy(pdata+24,fname); + pstrcpy(pdata+24,fname); break; default: return(ERROR(ERRDOS,ERRunknownlevel)); @@ -1260,7 +1260,7 @@ static int call_trans2setfilepathinfo(char *inbuf, char *outbuf, int length, /* set path info */ info_level = SVAL(params,0); fname = fname1; - strcpy(fname,¶ms[6]); + pstrcpy(fname,¶ms[6]); unix_convert(fname,cnum,0,&bad_path); if(!check_name(fname, cnum)) { @@ -1435,7 +1435,7 @@ static int call_trans2mkdir(char *inbuf, char *outbuf, int length, int bufsize, if (!CAN_WRITE(cnum)) return(ERROR(ERRSRV,ERRaccess)); - strcpy(directory, ¶ms[4]); + pstrcpy(directory, ¶ms[4]); DEBUG(3,("call_trans2mkdir : name = %s\n", directory)); @@ -1637,6 +1637,9 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize) num_params = num_params_sofar = SVAL(inbuf,smb_pscnt); num_data = num_data_sofar = SVAL(inbuf, smb_dscnt); + if (num_params > total_params || num_data > total_data) + exit_server("invalid params in reply_trans2"); + memcpy( params, smb_base(inbuf) + SVAL(inbuf, smb_psoff), num_params); memcpy( data, smb_base(inbuf) + SVAL(inbuf, smb_dsoff), num_data); @@ -1664,6 +1667,9 @@ int reply_trans2(char *inbuf,char *outbuf,int length,int bufsize) total_data = SVAL(inbuf, smb_tdscnt); num_params_sofar += (num_params = SVAL(inbuf,smb_spscnt)); num_data_sofar += ( num_data = SVAL(inbuf, smb_sdscnt)); + if (num_params_sofar > total_params || num_data_sofar > total_data) + exit_server("data overflow in trans2"); + memcpy( ¶ms[ SVAL(inbuf, smb_spsdisp)], smb_base(inbuf) + SVAL(inbuf, smb_spsoff), num_params); memcpy( &data[SVAL(inbuf, smb_sdsdisp)], diff --git a/source/smbd/vt_mode.c b/source/smbd/vt_mode.c index 0a4d50c217f..07558274a52 100644 --- a/source/smbd/vt_mode.c +++ b/source/smbd/vt_mode.c @@ -81,7 +81,7 @@ int VT_Start_utmp(void) setutent(); - strcpy(u.ut_line, VT_Line); + fstrcpy(u.ut_line, VT_Line); if((v = getutline(&u)) == NULL) { if(strncmp(VT_Line, "tty", 3) == 0) @@ -91,12 +91,12 @@ int VT_Start_utmp(void) else tt = VT_Line; - strcpy(u.ut_id, tt); + fstrcpy(u.ut_id, tt); u.ut_time = time((time_t*)0); } - strcpy(u.ut_user, "LOGIN"); - strcpy(u.ut_line, VT_Line); + fstrcpy(u.ut_user, "LOGIN"); + fstrcpy(u.ut_line, VT_Line); u.ut_pid = getpid(); u.ut_type = LOGIN_PROCESS; pututline(&u); @@ -118,10 +118,10 @@ int VT_Stop_utmp(void) if(VT_Line != NULL) { setutent(); - strcpy(u.ut_line, VT_Line); + fstrcpy(u.ut_line, VT_Line); if((v = getutline(&u)) != NULL) { - strcpy(v->ut_user, ""); + fstrcpy(v->ut_user, ""); v->ut_type = DEAD_PROCESS; v->ut_time = time((time_t*)0); pututline(v); diff --git a/source/utils/nmblookup.c b/source/utils/nmblookup.c index 25c94dcd6a0..aebbc4292ca 100644 --- a/source/utils/nmblookup.c +++ b/source/utils/nmblookup.c @@ -122,7 +122,7 @@ int main(int argc,char *argv[]) got_bcast = True; break; case 'i': - strcpy(scope,optarg); + fstrcpy(scope,optarg); strupper(scope); break; case 'M': @@ -135,7 +135,7 @@ int main(int argc,char *argv[]) DEBUGLEVEL = atoi(optarg); break; case 's': - strcpy(servicesf, optarg); + pstrcpy(servicesf, optarg); break; case 'h': usage(); @@ -172,7 +172,7 @@ int main(int argc,char *argv[]) char *p; struct in_addr ip; - strcpy(lookup,argv[i]); + fstrcpy(lookup,argv[i]); if (find_master) { if (*lookup == '-') { -- cgit v1.2.1 From 9d23bcbe5fac31017f5392478994df2d6a7e0d91 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 26 Sep 1997 12:47:59 +0000 Subject: preparing for release of 1.9.17p2 --- source/include/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/include/version.h b/source/include/version.h index afd20f5799d..76ccca122c6 100644 --- a/source/include/version.h +++ b/source/include/version.h @@ -1 +1 @@ -#define VERSION "1.9.17p1" +#define VERSION "1.9.17p2" -- cgit v1.2.1 From 9f8164d73583c32908ec3b9a6ae6630e78723553 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 26 Sep 1997 13:09:36 +0000 Subject: add info about p2 release --- WHATSNEW.txt | 42 ++++++++++++++++++------------------------ 1 file changed, 18 insertions(+), 24 deletions(-) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 500a4726bf2..fa3600d6c35 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,37 +1,31 @@ - WHATS NEW IN 1.9.17p1 - September 5 1997 - ======================================== + WHATS NEW IN 1.9.17p2 - September 26th 1997 + =========================================== -New stable patch release: Samba - version 1.9.17p1. ---------------------------------------------------- +Security fix release: Samba - version 1.9.17p2. +---------------------------------------------- -This is a patch release which superceedes the -last stable release of Samba, release 1.9.17. -This release fixes the few bugs that users reported -in the previous stable release (1.9.17). +This new stable release fixes a very important security hole in all +versions of Samba. -These bugfixes are : +The security hole allows a remote user to obtain root access on the +Samba server. A program which exploits this bug has been posted to the +internet. -Fix for DOS and Windows 95 clients having trouble -delting files on a Samba share in a DOS command line -environment. +The security hole is only known to affect Samba servers running on +Intel based hardware, and has only been demonstrated for Intel +Linux. It is likley that exploits for other architectures would be +very difficult but the possibility cannot be excluded completely. -Fixes to set the 'flag' bits correctly when talking to a -non-Samba WINS server. +This patch fixes the security hole for all platforms. -Fix for NT clients being dropped when using security=server. +This patch also adds a routine which will log a message when a user +attempts to take advantage of the security hole. -Fixes to the printer queue reporting code. - -Fix for the name map mangle bug (mangling .html -> .htm was -not working). - -If you are not affected by any of these problems then there -is no need to upgrade. - -The release notes from the previous stable release follow. +A number of other minor bugs have also been fixed in this release. The Samba Team. + -------------Previous release notes------------------------- New stable release of Samba - 1.9.17 -- cgit v1.2.1 From 4488171706e774eba415cced394551f40677089f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 19:40:59 +0000 Subject: Fixed you're -> your text that some pedant complained about :-). Jeremy (jallison@whistle.com). --- source/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 4235e7725e9..6d7a3577c6c 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -54,7 +54,7 @@ report a possible attack via the password buffer overflow bug static void overflow_attack(int len) { DEBUG(0,("ERROR: Invalid password length %d\n", len)); - DEBUG(0,("you're machine may be under attack by a user exploiting an old bug\n")); + DEBUG(0,("your machine may be under attack by a user exploiting an old bug\n")); DEBUG(0,("Attack was from IP=%s\n", client_addr())); exit_server("possible attack"); } -- cgit v1.2.1 From 898302839f25c33a5bd2e47be950e7c486456589 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 1997 21:43:44 +0000 Subject: Cause overflow attack to return an error code rather than terminate smbd. Terminating smbd allows a denial of service attack for multi-user NT servers. Jeremy (jallison@whistle.com) --- source/smbd/reply.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 6d7a3577c6c..d0beb285d73 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -56,7 +56,10 @@ static void overflow_attack(int len) DEBUG(0,("ERROR: Invalid password length %d\n", len)); DEBUG(0,("your machine may be under attack by a user exploiting an old bug\n")); DEBUG(0,("Attack was from IP=%s\n", client_addr())); +/* Don't exit server here - it allows a possible denial of service attack. */ +#if 0 exit_server("possible attack"); +#endif } @@ -253,6 +256,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen > MAX_PASSWORD_LENGTH) { overflow_attack(passlen); + return(ERROR(ERRSRV,ERRbadpw)); } { @@ -388,7 +392,10 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (Protocol < PROTOCOL_NT1) { smb_apasslen = SVAL(inbuf,smb_vwv7); if (smb_apasslen > MAX_PASSWORD_LENGTH) + { overflow_attack(smb_apasslen); + return(ERROR(ERRSRV,ERRbadpw)); + } memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); pstrcpy(user,smb_buf(inbuf)+smb_apasslen); @@ -422,6 +429,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen1 > MAX_PASSWORD_LENGTH) { overflow_attack(passlen1); + return(ERROR(ERRSRV,ERRbadpw)); } passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH); -- cgit v1.2.1 From 078da3c0f89641cf9cfa0109cd20a1626e6fdb14 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 27 Sep 1997 00:34:12 +0000 Subject: Put back changes to abort on overflow attack after conversation with Andrew. Jeremy (jallison@whistle.com) --- source/smbd/reply.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index d0beb285d73..f3a8ad22b8a 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -56,10 +56,7 @@ static void overflow_attack(int len) DEBUG(0,("ERROR: Invalid password length %d\n", len)); DEBUG(0,("your machine may be under attack by a user exploiting an old bug\n")); DEBUG(0,("Attack was from IP=%s\n", client_addr())); -/* Don't exit server here - it allows a possible denial of service attack. */ -#if 0 exit_server("possible attack"); -#endif } @@ -256,7 +253,6 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen > MAX_PASSWORD_LENGTH) { overflow_attack(passlen); - return(ERROR(ERRSRV,ERRbadpw)); } { @@ -394,7 +390,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (smb_apasslen > MAX_PASSWORD_LENGTH) { overflow_attack(smb_apasslen); - return(ERROR(ERRSRV,ERRbadpw)); } memcpy(smb_apasswd,smb_buf(inbuf),smb_apasslen); @@ -429,7 +424,6 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen1 > MAX_PASSWORD_LENGTH) { overflow_attack(passlen1); - return(ERROR(ERRSRV,ERRbadpw)); } passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH); -- cgit v1.2.1 From f5bd28c611cc76d640661bd51edbb454601ed474 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 29 Sep 1997 18:43:02 +0000 Subject: Fixed potential security bug with receive_smb passing in a pointer to a pstring instead of a full sized buffer. Pointed out by : Matt Power mhpower@mit.edu Jeremy (jallison@whistle.com) --- source/smbd/password.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/source/smbd/password.c b/source/smbd/password.c index ed79d658a66..6d84a5ff61c 100644 --- a/source/smbd/password.c +++ b/source/smbd/password.c @@ -1510,13 +1510,14 @@ BOOL check_hosts_equiv(char *user) int password_client = -1; static fstring pserver; +static char *secserver_inbuf = NULL; /**************************************************************************** attempted support for server level security ****************************************************************************/ BOOL server_cryptkey(char *buf) { - pstring inbuf,outbuf; + pstring outbuf; fstring pass_protocol; extern fstring remote_machine; char *p; @@ -1526,6 +1527,14 @@ BOOL server_cryptkey(char *buf) int port = SMB_PORT; BOOL ret; + if(secserver_inbuf == NULL) { + secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); + if(secserver_inbuf == NULL) { + DEBUG(0,("server_cryptkey: malloc fail for input buffer.\n")); + return False; + } + } + if (password_client >= 0) close(password_client); password_client = -1; @@ -1536,7 +1545,7 @@ BOOL server_cryptkey(char *buf) strcpy(pass_protocol,"NT LM 0.12"); } - bzero(inbuf,sizeof(inbuf)); + bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN); bzero(outbuf,sizeof(outbuf)); for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { @@ -1602,8 +1611,8 @@ BOOL server_cryptkey(char *buf) send_smb(password_client,outbuf); - if (!receive_smb(password_client,inbuf,5000) || - CVAL(inbuf,0) != 0x82) { + if (!receive_smb(password_client,secserver_inbuf,5000) || + CVAL(secserver_inbuf,0) != 0x82) { DEBUG(1,("%s rejected the session\n",pserver)); close(password_client); password_client = -1; return(False); @@ -1624,21 +1633,21 @@ BOOL server_cryptkey(char *buf) SSVAL(outbuf,smb_flg2,0x1); send_smb(password_client,outbuf); - ret = receive_smb(password_client,inbuf,5000); + ret = receive_smb(password_client,secserver_inbuf,5000); - if (!ret || CVAL(inbuf,smb_rcls) || SVAL(inbuf,smb_vwv0)) { + if (!ret || CVAL(secserver_inbuf,smb_rcls) || SVAL(secserver_inbuf,smb_vwv0)) { DEBUG(1,("%s rejected the protocol\n",pserver)); close(password_client); password_client= -1; return(False); } - if (!(CVAL(inbuf,smb_vwv1) & 1)) { + if (!(CVAL(secserver_inbuf,smb_vwv1) & 1)) { DEBUG(1,("%s isn't in user level security mode\n",pserver)); close(password_client); password_client= -1; return(False); } - memcpy(buf,inbuf,smb_len(inbuf)+4); + memcpy(buf,secserver_inbuf,smb_len(secserver_inbuf)+4); DEBUG(3,("password server OK\n")); @@ -1650,15 +1659,23 @@ attempted support for server level security ****************************************************************************/ BOOL server_validate(char *buf) { - pstring inbuf,outbuf; + pstring outbuf; BOOL ret; + if(secserver_inbuf == NULL) { + secserver_inbuf = (char *)malloc(BUFFER_SIZE + SAFETY_MARGIN); + if(secserver_inbuf == NULL) { + DEBUG(0,("server_validate: malloc fail for input buffer.\n")); + return False; + } + } + if (password_client < 0) { DEBUG(1,("%s not connected\n",pserver)); return(False); } - bzero(inbuf,sizeof(inbuf)); + bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN); memcpy(outbuf,buf,sizeof(outbuf)); /* send a session setup command */ @@ -1668,18 +1685,18 @@ BOOL server_validate(char *buf) set_message(outbuf,smb_numwords(outbuf),smb_buflen(outbuf),False); - SCVAL(inbuf,smb_rcls,1); + SCVAL(secserver_inbuf,smb_rcls,1); send_smb(password_client,outbuf); - ret = receive_smb(password_client,inbuf,5000); + ret = receive_smb(password_client,secserver_inbuf,5000); - if (!ret || CVAL(inbuf,smb_rcls) != 0) { + if (!ret || CVAL(secserver_inbuf,smb_rcls) != 0) { DEBUG(1,("password server %s rejected the password\n",pserver)); return(False); } /* if logged in as guest then reject */ - if ((SVAL(inbuf,smb_vwv2) & 1) != 0) { + if ((SVAL(secserver_inbuf,smb_vwv2) & 1) != 0) { DEBUG(1,("password server %s gave us guest only\n",pserver)); return(False); } -- cgit v1.2.1 From 82ab76981f47431e88a2aae4782fbebe6e5d8182 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 1997 17:13:32 +0000 Subject: Syncing up Support providers. --- docs/textdocs/Support.txt | 56 ++++++++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 22 deletions(-) diff --git a/docs/textdocs/Support.txt b/docs/textdocs/Support.txt index 0a5c41b1950..d482ac39123 100644 --- a/docs/textdocs/Support.txt +++ b/docs/textdocs/Support.txt @@ -33,7 +33,7 @@ Region Number of entries ASIA 1 AUSTRALIA & NEW ZEALAND 18 CANADA 8 - EUROPE 34 + EUROPE 35 MIDDLE EAST 1 AFRICA @@ -1403,32 +1403,32 @@ http://www.alcove.fr Phone number: +33 01 40 85 80 06 ------------------------------------------------------------------------------ BERLIN - GERMANY -Name: innominate GbR -Address: Soldiner Str. 96, 13359 Berlin; Bundesland: Berlin; -Country: Germany -Phone: +49 30 49308195, +49 177 2649655 (mobil) -Fax: +49 30 49308196 -EMail: innominate@poboxes.com +Name: innominate + Multifunktionale Serverloesungen und IT-Dienstleistungen -Contact : Sascha Ottolski +Address: Stresemannstraße 128, 10117 Berlin +Country: Germany +Phone: +49 30 202 90 477 +Fax: +49 30 202 90 249 +EMail: info@innominate.de +Web: http://innominate.de Type of support: vor Ort, Email, Fernzugriff ueber Internet/ISDN, -Special -expertise: Wir verfuegen ueber umfangreiche Erfahrung mit Samba, vor allem - in Internet- und Intranetumgebungen. Neben Beratung, Dienstleistung - und Schulung bieten wir auch individuell vorkonfigurierte - Kommunikationsserver ("Lingo") auf der Basis von Linux an. - Neben anderen Modulen (ISDN/Internet/Intranet/Email/Proxy - u.a.) ist in Lingo ein Fileserver-Modul auf Samba-Basis inklusive - einem mehrstufigen Firewallsystem enthalten. - Außerdem verfuegt Lingo ueber eine grafische Administrations- - oberflaeche, mit der z.B. das Hinzufuegen von neuen Benutzern - von jedem Client per WWW-Browser moeglich ist. +Wir verfuegen ueber umfangreiche Erfahrung mit Samba, vor allem +in Intranetumgebungen. Neben Beratung, Dienstleistung +und Schulung bieten wir auch individuell vorkonfigurierte +Kommunikationsserver ("Lingo") auf der Basis von Linux an. +Neben anderen Modulen (ISDN/Internet/Intranet/Email/Proxy +u.a.) ist in Lingo ein Fileserver-Modul auf Samba-Basis inklusive +einem mehrstufigen Firewallsystem enthalten. +Außerdem verfuegt Lingo ueber eine grafische Administrations- +oberflaeche, mit der z.B. das Hinzufuegen von neuen Benutzern +von jedem Client per WWW-Browser moeglich ist. -Sample prices: - Komplettpreise fuer Lingo nach Vereinbarung - - 120 DM/Stunde fuer Dienstleistung - - Schulung nach Vereinbarung +Prices: Komplettpreise fuer Lingo nach Vereinbarung + 120 DM/Stunde fuer Dienstleistung + Schulung nach Vereinbarung ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ @@ -1547,6 +1547,18 @@ We are a Premium Partner of SCO and know and have used samba for four years. Our engineers know a lot about the installation of SCO Unix. ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +GREECE + +Yiorgos Adamopoulos +Electrical and Computer Engineer +email: adamo@InterWorks.org + +I can provide Samba support for the following operating systems throughout the +whole of Greece: Windows 3.11/95/NT, Ultrix, HP-UX, NetBSD, OpenBSD, SunOS, +Solaris, Linux, Irix. +------------------------------------------------------------------------------ + ------------------------------------------------------------------------------ SZEGED - HUNGARY -- cgit v1.2.1 From 1de1a22d0cd4ca1a977f35411ca57ce0768a46d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Oct 1997 19:54:33 +0000 Subject: locking.c: Finally fixed nasty crash bug when deleting invalid share mode entries. util.c: Tried to stop put_ip core dump seemingly caused by bad returns from gethostbyname. Jeremy (jallison@whistle.com) --- source/lib/util.c | 4 ++++ source/locking/locking.c | 7 ++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/source/lib/util.c b/source/lib/util.c index 0c4999c789c..7f785332e6a 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -3150,6 +3150,10 @@ uint32 interpret_addr(char *str) DEBUG(3,("Get_Hostbyname: Unknown host. %s\n",str)); return 0; } + if(hp->h_addr == NULL) { + DEBUG(3,("Get_Hostbyname: host address is invalid for host %s.\n",str)); + return 0; + } putip((char *)&res,(char *)hp->h_addr); } diff --git a/source/locking/locking.c b/source/locking/locking.c index c2a06cac75c..868902963fe 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -206,7 +206,7 @@ file dev = %d, ino = %d in hash_bucket %d\n", dev, inode, hash_entry)); { DEBUG(0,("ERROR:get_share_modes (FAST_SHARE_MODES): Deleting old share mode \ record due to old locking version %d for file dev = %d, inode = %d in hash \ -bucket %d",file_scanner_p->locking_version, dev, inode, hash_entry)); +bucket %d\n",file_scanner_p->locking_version, dev, inode, hash_entry)); if(file_prev_p == file_scanner_p) mode_array[hash_entry] = file_scanner_p->next_offset; else @@ -241,6 +241,7 @@ bucket %d",file_scanner_p->locking_version, dev, inode, hash_entry)); { /* Delete this share mode entry */ share_mode_entry *delete_entry_p = entry_scanner_p; + int share_mode = entry_scanner_p->share_mode; if(entry_prev_p == entry_scanner_p) { @@ -270,8 +271,8 @@ for dev = %d, ino = %d, hashbucket %d\n", file_scanner_p->num_share_mode_entries DEBUG(0,("get_share_modes (FAST_SHARE_MODES): process %d no longer exists and \ it left a share mode entry with mode 0x%X for file dev = %d, ino = %d in hash \ -bucket (number of entries now = %d)\n", - pid, entry_scanner_p->share_mode, dev, inode, hash_entry, +bucket %d (number of entries now = %d)\n", + pid, share_mode, dev, inode, hash_entry, file_scanner_p->num_share_mode_entries)); smb_shm_free(smb_shm_addr2offset(delete_entry_p)); -- cgit v1.2.1 From bef10e388ac8661afc465a64524ba55f8c5bea0c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 7 Oct 1997 11:18:26 +0000 Subject: get rid of SIGCLD_IGNORE for HPUX. A user reported it causing lots of defunct smbd processes. Andrew --- source/include/includes.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/include/includes.h b/source/include/includes.h index e66ceb2d70c..4e48e87a7c1 100644 --- a/source/include/includes.h +++ b/source/include/includes.h @@ -563,7 +563,9 @@ char *mktemp(char *); /* No standard include */ #define USE_SETSID #define USE_SETRES #define DEFAULT_PRINTING PRINT_HPUX -#define SIGCLD_IGNORE +/* Ken Weiss tells us that SIGCLD_IGNORE is + not good for HPUX */ +/* #define SIGCLD_IGNORE */ #endif /* HPUX */ -- cgit v1.2.1 From d98f9bbbdef02e46428c6eb954ebc5513bbc5c1c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 7 Oct 1997 14:36:51 +0000 Subject: increase the debug level in the "added interface" debug line --- source/lib/interface.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/lib/interface.c b/source/lib/interface.c index 940af1eccf4..147425d0fc1 100644 --- a/source/lib/interface.c +++ b/source/lib/interface.c @@ -337,9 +337,9 @@ static void interpret_interfaces(char *s, struct interface **interfaces, iface->next = NULL; (*interfaces) = last_iface = iface; - DEBUG(1,("Added interface ip=%s ",inet_ntoa(iface->ip))); - DEBUG(1,("bcast=%s ",inet_ntoa(iface->bcast))); - DEBUG(1,("nmask=%s\n",inet_ntoa(iface->nmask))); + DEBUG(2,("Added interface ip=%s ",inet_ntoa(iface->ip))); + DEBUG(2,("bcast=%s ",inet_ntoa(iface->bcast))); + DEBUG(2,("nmask=%s\n",inet_ntoa(iface->nmask))); } -- cgit v1.2.1 From 3e16fc01ed748129c1587acc6330730f3cfbf77a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 7 Oct 1997 14:38:31 +0000 Subject: increase the debug level in the "client requested max ..." debug line --- source/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/smbd/reply.c b/source/smbd/reply.c index f3a8ad22b8a..31915e6acac 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -598,7 +598,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (!done_sesssetup) max_send = MIN(max_send,smb_bufsize); - DEBUG(1,(" Client requested max send size of %d\n", max_send)); + DEBUG(5,(" Client requested max send size of %d\n", max_send)); done_sesssetup = True; -- cgit v1.2.1 From 1c510a4c3c59ebdf170b73c0fb082d0fa1fabf25 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Oct 1997 19:24:44 +0000 Subject: Fixed nasty (but rare) race mode condition with slow share mode code. Jeremy (jallison@whistle.com) --- source/locking/locking.c | 64 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 14 deletions(-) diff --git a/source/locking/locking.c b/source/locking/locking.c index 868902963fe..b86ef76a2b8 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -612,13 +612,59 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok { int old_umask; + BOOL gotlock = False; unbecome_user(); old_umask = umask(0); + + /* + * There was a race condition in the original slow share mode code. + * A smbd could open a share mode file, and before getting + * the lock, another smbd could delete the last entry for + * the share mode file and delete the file entry from the + * directory. Thus this smbd would be left with a locked + * share mode fd attached to a file that no longer had a + * directory entry. Thus another smbd would think that + * there were no outstanding opens on the file. To fix + * this we now check we can do a stat() call on the filename + * before allowing the lock to proceed, and back out completely + * and try the open again if we cannot. + * Jeremy Allison (jallison@whistle.com). + */ + + do + { + struct stat dummy_stat; #ifdef SECURE_SHARE_MODES - fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600); + fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0600); #else /* SECURE_SHARE_MODES */ - fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); + fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); #endif /* SECURE_SHARE_MODES */ + + /* At this point we have an open fd to the share mode file. + Lock the first byte exclusively to signify a lock. */ + if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) + { + DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n", + strerror(errno))); + close(fd); + return False; + } + + /* + * If we cannot stat the filename, the file was deleted between + * the open and the lock call. Back out and try again. + */ + + if(stat(fname, &dummy_stat)!=0) + { + DEBUG(2,("lock_share_entry: Re-issuing open on %s to fix race. Error was %s\n", + fname, strerror(errno))); + close(fd); + } + else + gotlock = True; + } while(!gotlock); + umask(old_umask); if(!become_user(cnum,Connections[cnum].vuid)) { @@ -636,18 +682,8 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok } } - /* At this point we have an open fd to the share mode file. - Lock the first byte exclusively to signify a lock. */ - if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) - { - DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n", - strerror(errno))); - close(fd); - return False; - } - - *ptok = (share_lock_token)fd; - return True; + *ptok = (share_lock_token)fd; + return True; } /******************************************************************* -- cgit v1.2.1 From 6e1164b7c55668ebd0b6e97d7f05409134b39c1f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 8 Oct 1997 00:24:38 +0000 Subject: Added ERROR_MORE_DATA fix when replies have been truncated. Jeremy (jallison@whistle.com) --- source/smbd/ipc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index 9aaf03e6c4f..a0a4ec8fc73 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -1074,7 +1074,7 @@ static BOOL api_RNetServerEnum(int cnum, uint16 vuid, char *param, char *data, *rparam_len = 8; *rparam = REALLOC(*rparam,*rparam_len); - SSVAL(*rparam,0,NERR_Success); + SSVAL(*rparam,0,(missed == 0 ? NERR_Success : ERROR_MORE_DATA)); SSVAL(*rparam,2,0); SSVAL(*rparam,4,counted); SSVAL(*rparam,6,counted+missed); -- cgit v1.2.1 From 07b878e2027539b6721f41b9f5670d50d9da7071 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 8 Oct 1997 02:18:45 +0000 Subject: put this in 1.9.17 also ... change the semantics of hosts allow/hosts deny so that a global setting applies to all shares regardless of any settings on other shares. This allows us to immediately drop a connection if it does not come from a allowed host, without even parsing the first SMB packet. The next time we get a nasty security hole we can offer people the option of just setting their hosts allow line. If we drop a connection in this way we generate a "Not listening for calling name" response and then exit. --- docs/manpages/smb.conf.5 | 9 +++++---- source/smbd/server.c | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5 index a0a96f26ff6..5c4ce3375fe 100644 --- a/docs/manpages/smb.conf.5 +++ b/docs/manpages/smb.conf.5 @@ -720,10 +720,11 @@ then the "load printers" option is easier. A synonym for this parameter is 'hosts allow'. This parameter is a comma delimited set of hosts which are permitted to access -a services. If specified in the [global] section, matching hosts will be -allowed access to any service that does not specifically exclude them from -access. Specific services my have their own list, which override those -specified in the [global] section. +a service. + +If specified in the [global] section then it will apply to all +services, regardless of whether the individual service has a different +setting. You can specify the hosts by name or IP number. For example, you could restrict access to only the hosts on a Class C subnet with something like diff --git a/source/smbd/server.c b/source/smbd/server.c index 2bc0e023158..35a7c730be4 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -4068,6 +4068,23 @@ static void process(void) } } + if (trans_num == 0) { + /* on the first packet, check the global hosts allow/ hosts + deny parameters before doing any parsing of the packet + passed to us by the client. This prevents attacks on our + parsing code from hosts not in the hosts allow list */ + if (!check_access(-1)) { + /* send a negative session response "not listining + on calling name" */ + static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81}; + DEBUG(1,("%s Connection denied from %s\n", + timestring(),client_addr())); + send_smb(Client,(char *)buf); + exit_server("connection denied"); + } + } + + msg_type = CVAL(InBuffer,0); msg_flags = CVAL(InBuffer,1); type = CVAL(InBuffer,smb_com); -- cgit v1.2.1 From 2614cd1d35ab53e952e5bcfbb1d50b0feeefeeb6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Oct 1997 00:43:55 +0000 Subject: predict.c: stop lseek from extending file. Hard to test. proto.h: updated. quotas.c: Added FreeBSD fixes. server.c: Added quota overflow fix for large filesystems. Rolled back to old error codes. Jeremy (jallison@whistle.com) --- source/smbd/predict.c | 39 ++++++++++++++++++++++++++------------- source/smbd/quotas.c | 27 ++++++++++++++++++++++++++- source/smbd/server.c | 30 ++++++++++++++++++++++++++++-- 3 files changed, 80 insertions(+), 16 deletions(-) diff --git a/source/smbd/predict.c b/source/smbd/predict.c index 691d8fbb4e0..7d6b2498f5a 100644 --- a/source/smbd/predict.c +++ b/source/smbd/predict.c @@ -53,24 +53,37 @@ int read_predict(int fd,int offset,char *buf,char **ptr,int num) offset >= rp_offset && possible>0 && smb_last_time-rp_time < rp_timeout) - { - ret = possible; - if (buf) - memcpy(buf,rp_buffer + (offset-rp_offset),possible); - else - *ptr = rp_buffer + (offset-rp_offset); - DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num)); - } + { + ret = possible; + if (buf) + memcpy(buf,rp_buffer + (offset-rp_offset),possible); + else + *ptr = rp_buffer + (offset-rp_offset); + DEBUG(5,("read-prediction gave %d bytes of %d\n",ret,num)); + } if (ret == num) { predict_skip = True; } else { - predict_skip = False; + struct stat rp_stat; + + /* Find the end of the file - ensure we don't + read predict beyond it. */ + if(fstat(fd,&rp_stat) < 0) + { + DEBUG(0,("read-prediction failed on fstat. Error was %s\n", strerror(errno))); + predict_skip = True; + } + else + { + predict_skip = False; - /* prepare the next prediction */ - rp_predict_fd = fd; - rp_predict_offset = offset + num; - rp_predict_length = num; + /* prepare the next prediction */ + rp_predict_fd = fd; + /* Make sure we don't seek beyond the end of the file. */ + rp_predict_offset = MIN((offset + num),rp_stat.st_size); + rp_predict_length = num; + } } if (ret < 0) ret = 0; diff --git a/source/smbd/quotas.c b/source/smbd/quotas.c index d4f746c9e36..2d238dfaf17 100644 --- a/source/smbd/quotas.c +++ b/source/smbd/quotas.c @@ -416,10 +416,12 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) } return (True); } + #else #ifdef __FreeBSD__ #include +#include #elif AIX /* AIX quota patch from Ole Holm Nielsen */ #include @@ -463,7 +465,25 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) } #else /* USE_SETRES */ #if defined(__FreeBSD__) - r= quotactl(path,Q_GETQUOTA,euser_id,(char *) &D); + { + /* FreeBSD patches from Marty Moll */ + uid_t user_id; + gid_t egrp_id; + + /* Need to be root to get quotas in FreeBSD */ + user_id = getuid(); + egrp_id = getegid(); + setuid(0); + seteuid(0); + r= quotactl(path,QCMD(Q_GETQUOTA,USRQUOTA),euser_id,(char *) &D); + + /* As FreeBSD has group quotas, if getting the user + quota fails, try getting the group instead. */ + if (r) + r= quotactl(path,QCMD(Q_GETQUOTA,GRPQUOTA),egrp_id,(char *) &D); + setuid(user_id); + seteuid(euser_id); + } #elif defined(AIX) /* AIX has both USER and GROUP quotas: Get the USER quota (ohnielse@fysik.dtu.dk) */ @@ -474,7 +494,12 @@ BOOL disk_quotas(char *path, int *bsize, int *dfree, int *dsize) #endif /* USE_SETRES */ /* Use softlimit to determine disk space, except when it has been exceeded */ +#if defined(__FreeBSD__) + *bsize = DEV_BSIZE; +#else /* !__FreeBSD__ */ *bsize = 1024; +#endif /*!__FreeBSD__ */ + if (r) { if (errno == EDQUOT) diff --git a/source/smbd/server.c b/source/smbd/server.c index 35a7c730be4..8e1bc152ffd 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -703,7 +703,15 @@ int disk_free(char *path,int *bsize,int *dfree,int *dsize) dfree_retval : dfreeq_retval ; /* maybe dfree and dfreeq are calculated using different bsizes so convert dfree from bsize into bsizeq */ - *dfree = ((*dfree) * (*bsize)) / (bsizeq); + /* avoid overflows due to multiplication, so do not: + *dfree = ((*dfree) * (*bsize)) / (bsizeq); + bsize and bsizeq are powers of 2 so its better to + to divide them getting a multiplication or division factor + for dfree. Rene Nieuwenhuizen (07-10-1997) */ + if (*bsize >= bsizeq) + *dfree = *dfree * (*bsize / bsizeq); + else + *dfree = *dfree / (bsizeq / *bsize); *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; *bsize = bsizeq; *dsize = dsizeq; @@ -793,7 +801,15 @@ if ((*bsize) < 512 || (*bsize)>0xFFFF) *bsize = 1024; dfree_retval : dfreeq_retval ; /* maybe dfree and dfreeq are calculated using different bsizes so convert dfree from bsize into bsizeq */ - *dfree = ((*dfree) * (*bsize)) / (bsizeq); + /* avoid overflows due to multiplication, so do not: + *dfree = ((*dfree) * (*bsize)) / (bsizeq); + bsize and bsizeq are powers of 2 so its better to + to divide them getting a multiplication or division factor + for dfree. Rene Nieuwenhuizen (07-10-1997) */ + if (*bsize >= bsizeq) + *dfree = *dfree * (*bsize / bsizeq); + else + *dfree = *dfree / (bsizeq / *bsize); *dfree = ( *dfree < dfreeq ) ? *dfree : dfreeq ; *bsize = bsizeq; *dsize = dsizeq; @@ -1963,7 +1979,11 @@ struct {EPERM,ERRDOS,ERRnoaccess}, {EACCES,ERRDOS,ERRnoaccess}, {ENOENT,ERRDOS,ERRbadfile}, +#if 0 /* Go back to old method for now. */ {ENOTDIR,ERRDOS,ERRbaddirectory}, +#else + {ENOTDIR,ERRDOS,ERRbadpath}, +#endif {EIO,ERRHRD,ERRgeneral}, {EBADF,ERRSRV,ERRsrverror}, {EINVAL,ERRSRV,ERRsrverror}, @@ -1984,6 +2004,7 @@ struct {0,0,0} }; +#if 0 /* Go back to old method for now. */ /* Mapping for old clients. */ struct @@ -1998,6 +2019,8 @@ struct {0,0,0} }; +#endif /* Go back to old method for now. */ + /**************************************************************************** create an error packet from errno ****************************************************************************/ @@ -2028,6 +2051,8 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int } } +#if 0 /* Go back to old method for now. */ + /* Make sure we don't return error codes that old clients don't understand. */ @@ -2050,6 +2075,7 @@ int unix_error_packet(char *inbuf,char *outbuf,int def_class,uint32 def_code,int break; } } +#endif /* Go back to old method for now. */ return(error_packet(inbuf,outbuf,eclass,ecode,line)); } -- cgit v1.2.1 From 4bf12a48435b3ec504439251638586c76742010c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 9 Oct 1997 06:47:20 +0000 Subject: change MAX_PASSWORD_LENGTH to MAX_PASS_LEN to prevent conflict on some systems --- source/include/local.h | 2 +- source/smbd/reply.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/source/include/local.h b/source/include/local.h index 9548bf74b6b..f5f2c318180 100644 --- a/source/include/local.h +++ b/source/include/local.h @@ -43,7 +43,7 @@ #define WORDMAX 0xFFFF /* the maximum password length before we declare a likely attack */ -#define MAX_PASSWORD_LENGTH 200 +#define MAX_PASS_LEN 200 /* separators for lists */ #define LIST_SEP " \t,;:\n\r" diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 31915e6acac..7925add45f3 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -251,7 +251,7 @@ int reply_tcon_and_X(char *inbuf,char *outbuf,int length,int bufsize) if ((SVAL(inbuf,smb_vwv2) & 0x1) != 0) close_cnum(SVAL(inbuf,smb_tid),vuid); - if (passlen > MAX_PASSWORD_LENGTH) { + if (passlen > MAX_PASS_LEN) { overflow_attack(passlen); } @@ -387,7 +387,7 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (Protocol < PROTOCOL_NT1) { smb_apasslen = SVAL(inbuf,smb_vwv7); - if (smb_apasslen > MAX_PASSWORD_LENGTH) + if (smb_apasslen > MAX_PASS_LEN) { overflow_attack(smb_apasslen); } @@ -422,12 +422,12 @@ int reply_sesssetup_and_X(char *inbuf,char *outbuf,int length,int bufsize) if (passlen1 != 24 && passlen2 != 24) doencrypt = False; - if (passlen1 > MAX_PASSWORD_LENGTH) { + if (passlen1 > MAX_PASS_LEN) { overflow_attack(passlen1); } - passlen1 = MIN(passlen1, MAX_PASSWORD_LENGTH); - passlen2 = MIN(passlen2, MAX_PASSWORD_LENGTH); + passlen1 = MIN(passlen1, MAX_PASS_LEN); + passlen2 = MIN(passlen2, MAX_PASS_LEN); if(doencrypt) { /* Save the lanman2 password and the NT md4 password. */ -- cgit v1.2.1 From a70d0fc26ff0eed6ab4adea1b17f2d184d133d05 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 10 Oct 1997 02:35:55 +0000 Subject: fixed the log wrapping bug. This is a very nasty bug that I think explains quite a few intermittent problems people have been having with Samba. It may be worth checking on other cases where errno can be overwritten by seemingly innocuous things (in this case a DEBUG() line) --- source/lib/util.c | 30 +++++++++++++++++------------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/source/lib/util.c b/source/lib/util.c index 7f785332e6a..459745b8b14 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -156,7 +156,7 @@ static void check_log_size(void) int maxlog; struct stat st; - if (debug_count++ < 100) return; + if (debug_count++ < 100 || getuid() != 0) return; maxlog = lp_max_log_size() * 1024; if (!dbf || maxlog <= 0) return; @@ -175,7 +175,6 @@ static void check_log_size(void) debug_count=0; } - /******************************************************************* write an debug message on the debugfile. This is called by the DEBUG macro @@ -190,7 +189,8 @@ va_dcl char *format_str; #endif va_list ap; - + int old_errno = errno; + if (stdout_logging) { #ifdef __STDC__ va_start(ap, format_str); @@ -200,6 +200,7 @@ va_dcl #endif vfprintf(dbf,format_str,ap); va_end(ap); + errno = old_errno; return(0); } @@ -207,16 +208,17 @@ va_dcl if (!lp_syslog_only()) #endif { - if (!dbf) - { - int oldumask = umask(022); - dbf = fopen(debugf,"w"); - umask(oldumask); - if (dbf) - setbuf(dbf,NULL); - else - return(0); - } + if (!dbf) { + int oldumask = umask(022); + dbf = fopen(debugf,"w"); + umask(oldumask); + if (dbf) { + setbuf(dbf,NULL); + } else { + errno = old_errno; + return(0); + } + } } #ifdef SYSLOG @@ -273,6 +275,8 @@ va_dcl check_log_size(); + errno = old_errno; + return(0); } -- cgit v1.2.1 From 832a05825476d6d5d80245e28f490104b4d84c99 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Oct 1997 22:59:43 +0000 Subject: Updating for 1.9.17p3 release. Jeremy (jallison@whistle.com) --- WHATSNEW.txt | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index fa3600d6c35..b3aa7d78a17 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,6 +1,52 @@ - WHATS NEW IN 1.9.17p2 - September 26th 1997 + WHATS NEW IN 1.9.17p2 - October 13th 1997 =========================================== +Update release: Samba - version 1.9.17p3. +----------------------------------------- + +This is the latest stable release of Samba. This is the +version that all production Samba servers should be running +for all current bug-fixes. + +Here are a list of the fixes in this release (the fixes +introduced between 1.9.17p2 and 1.9.17p3) : + +1). Truncation of long browse lists. +2). Crash bug when dead share mode memory entries need removing. +3). Race condition in slow share mode code. +4). Potential buffer overflow from password server. +5). Fix for read-prediction growing read-only files. +6). Many quota code fixes. +7). Fix for spelling mistake in attack warning :-). +8). Removed 'ERRbaddirectory' error code - caused problem with + Visual Basic apps. +9). Allow 'hosts allow/deny' to work before client packet parsed. +10). Wrapping log file causes incorrect errors to be returned to + the clients. +11). Crash fix for nmbd Get_Hostbyname bad return. + +Reporting bugs +-------------- + +The Samba Team believes that this is a stable +production release, but all software has bugs. +If you have problems, or think you have found a +bug please email a report to : + +samba-bugs@samba.anu.edu.au + +Stating the version number of Samba that you +are running, and *full details* of the steps +we need to reproduce the problem. + +As always, all bugs are our responsibility. + +Regards, + + The Samba Team. + +-------------Previous release notes------------------------- + Security fix release: Samba - version 1.9.17p2. ---------------------------------------------- -- cgit v1.2.1 From bbbe907cc41ad25a9c013d2254384b399f7c36d7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 10 Oct 1997 23:02:49 +0000 Subject: Added Luke's changes to release tree. Jeremy (jallison@whistle.com) --- docs/textdocs/BROWSING.txt | 155 +++++++++++++++++++++++---------------------- 1 file changed, 78 insertions(+), 77 deletions(-) diff --git a/docs/textdocs/BROWSING.txt b/docs/textdocs/BROWSING.txt index d8362f15299..4e0a49f2202 100644 --- a/docs/textdocs/BROWSING.txt +++ b/docs/textdocs/BROWSING.txt @@ -8,8 +8,8 @@ Summary: This describes how to configure Samba for improved browsing. OVERVIEW: ========= SMB networking provides a mechanism by which clients can access a list -of machines that are available within the network. This list is called -the browse list and is heavily used by all SMB clients. Configuration +of machines that are available within the network. This list is called +the browse list and is heavily used by all SMB clients. Configuration of SMB browsing has been problematic for some Samba users, hence this document. @@ -17,7 +17,7 @@ document. BROWSING ======== -Samba now fully supports browsing. The browsing is supported by nmbd +Samba now fully supports browsing. The browsing is supported by nmbd and is also controlled by options in the smb.conf file (see smb.conf(5)). Samba can act as a local browse master for a workgroup and the ability @@ -28,10 +28,13 @@ Samba can also act as a domain master browser for a workgroup. This means that it will collate lists from local browse masters into a wide area network server list. In order for browse clients to resolve the names they may find in this list, it is recommended that -both samba and your clients use a WINS server +both samba and your clients use a WINS server. Note that you should NOT set Samba to be the domain master for a -workgroup that has the same name as an NT Domain. +workgroup that has the same name as an NT Domain: on each wide area +network, you must only ever have one domain master browser per workgroup, +regardless of whether it is NT, Samba or any other type of domain master +that is providing this service. [Note that nmbd can be configured as a WINS server, but it is not necessary to specifically use samba as your WINS server. NTAS can @@ -48,10 +51,10 @@ Samba becomes a part of. Samba also has a useful option for a Samba server to offer itself for browsing on another subnet. It is recommended that this option is only used for 'unusual' purposes: announcements over the internet, for -example. See "remote announce" in the smb.conf man page. +example. See "remote announce" in the smb.conf man page. If something doesn't work then hopefully the log.nmb file will -help you track down the problem. Try a debug level of 2 or 3 for +help you track down the problem. Try a debug level of 2 or 3 for finding problems. Note that if it doesn't work for you, then you should still be able to @@ -59,14 +62,14 @@ type the server name as \\SERVER in filemanager then hit enter and filemanager should display the list of available shares. Some people find browsing fails because they don't have the global -"guest account" set to a valid account. Remember that the IPC$ +"guest account" set to a valid account. Remember that the IPC$ connection that lists the shares is done as guest, and thus you must have a valid guest account. Also, a lot of people are getting bitten by the problem of too many -parameters on the command line of nmbd in inetd.conf. This trick is to +parameters on the command line of nmbd in inetd.conf. This trick is to not use spaces between the option and the parameter (eg: -d2 instead -of -d 2), and to not use the -B and -N options. New versions of nmbd +of -d 2), and to not use the -B and -N options. New versions of nmbd are now far more likely to correctly find your broadcast and network addess, so in most cases these aren't needed. @@ -74,23 +77,23 @@ The other big problem people have is that their broadcast address, netmask or IP address is wrong (specified with the "interfaces" option in smb.conf) + BROWSING ACROSS SUBNETS ======================= -With the release of Samba 1.9.17(alpha1 and above) Samba has been -updated to enable it to support the replication of browse lists -across subnet boundaries. New code and options have been added to -achieve this. This section describes how to set this feature up -in different settings. +With the release of Samba 1.9.17, Samba has been updated to enable +it to support the replication of browse lists across subnet +boundaries. New code and options have been added to achieve this. +This section describes how to set this feature up in different settings. -To see browse lists that span TCP/IP subnets (ie. networks separated +To see browse lists that span TCP/IP subnets (ie. networks separated by routers that don't pass broadcast traffic) you must set up at least -one WINS server. The WINS server acts as a DNS for NetBIOS names, allowing +one WINS server. The WINS server acts as a DNS for NetBIOS names, allowing NetBIOS name to IP address translation to be done by doing a direct -query of the WINS server. This is done via a directed UDP packet on -port 137 to the WINS server machine. The reason for a WINS server is +query of the WINS server. This is done via a directed UDP packet on +port 137 to the WINS server machine. The reason for a WINS server is that by default, all NetBIOS name to IP address translation is done -by broadcasts from the querying machine. This means that machines +by broadcasts from the querying machine. This means that machines on one subnet will not be able to resolve the names of machines on another subnet without using a WINS server. @@ -104,7 +107,7 @@ How does cross subnet browsing work ? ===================================== Cross subnet browsing is a complicated dance, containing multiple -moving parts. It has taken Microsoft several years to get the code +moving parts. It has taken Microsoft several years to get the code that achieves this correct, and Samba lags behind in some areas. However, with the 1.9.17 release, Samba is capable of cross subnet browsing when configured correctly. @@ -127,38 +130,38 @@ Consider a network set up as follows : (WINS) Consisting of 3 subnets (1, 2, 3) conneted by two routers -(R1, R2) - these do not pass broadcasts. Subnet 1 has 5 machines -on it, subnet 2 has 4 machines, subnet 3 has 4 machines. Assume +(R1, R2) - these do not pass broadcasts. Subnet 1 has 5 machines +on it, subnet 2 has 4 machines, subnet 3 has 4 machines. Assume for the moment that all these machines are configured to be in the -same workgroup (for simplicities sake). Machine N1_C on subnet 1 -is configured as Domain Master Browser (ie. it will collate the -browse lists for the workgroup). Machine N2_D is configured as +same workgroup (for simplicities sake). Machine N1_C on subnet 1 +is configured as Domain Master Browser (ie. it will collate the +browse lists for the workgroup). Machine N2_D is configured as WINS server and all the other machines are configured to register their NetBIOS names with it. As all these machines are booted up, elections for master browsers -will take place on each of the three subnets. Assume that machine +will take place on each of the three subnets. Assume that machine N1_C wins on subnet 1, N2_B wins on subnet 2, and N3_D wins on subnet 3 - these machines are known as local master browsers for -their particular subnet. N1_C has an advantage in winning as the +their particular subnet. N1_C has an advantage in winning as the local master browser on subnet 1 as it is set up as Domain Master Browser. On each of the three networks, machines that are configured to offer sharing services will broadcast that they are offering -these services. The local master browser on each subnet will +these services. The local master browser on each subnet will receive these broadcasts and keep a record of the fact that -the machine is offering a service. This list of records is -the basis of the browse list. For this case, assume that +the machine is offering a service. This list of records is +the basis of the browse list. For this case, assume that all the machines are configured to offer services so all machines will be on the browse list. For each network, the local master browser on that network is considered 'authoritative' for all the names it receives via -local broadcast. This is because a machine seen by the local +local broadcast. This is because a machine seen by the local master browser via a local broadcast must be on the same network as the local master browser and thus is a 'trusted' -and 'verifiable' resource. Machines on other networks that +and 'verifiable' resource. Machines on other networks that the local master browsers learn about when collating their browse lists have not been directly seen - these records are called 'non-authoritative'. @@ -178,21 +181,21 @@ Subnet3 N3_D N3_A, N3_B, N3_C, N3_D Note that at this point all the subnets are separate, no machine is seen across any of the subnets. -Now examine subnet 2. As soon as N2_B has become the local +Now examine subnet 2. As soon as N2_B has become the local master browser it looks for a Domain master browser to synchronize -its browse list with. It does this by querying the WINS server +its browse list with. It does this by querying the WINS server (N2_D) for the IP address associated with the NetBIOS name -WORKGROUP<1B>. This name was registerd by the Domain master +WORKGROUP<1B>. This name was registerd by the Domain master browser (N1_C) with the WINS server as soon as it was booted. Once N2_B knows the address of the Domain master browser it tells it that is the local master browser for subnet 2 by sending a MasterAnnouncement packet as a UDP port 138 packet. -It then synchronizes with it by doing a NetServerEnum2 call. This +It then synchronizes with it by doing a NetServerEnum2 call. This tells the Domain Master Browser to send it all the server -names it knows about. Once the domain master browser receives +names it knows about. Once the domain master browser receives the MasterAnnouncement packet it schedules a synchronization -request to the sender of that packet. After both synchronizations +request to the sender of that packet. After both synchronizations are done the browse lists look like : Subnet Browse Master List @@ -212,10 +215,10 @@ subnets 1 or 2 will see all the servers on both, users on subnet 3 will still only see the servers on their own subnet. The same sequence of events that occured for N2_B now occurs -for the local master browser on subnet 3 (N3_D). When it +for the local master browser on subnet 3 (N3_D). When it synchronizes browse lists with the domain master browser (N1_A) it gets both the server entries on subnet 1, and those on -subnet 2. After N3_D has synchronized with N1_C and vica-versa +subnet 2. After N3_D has synchronized with N1_C and vica-versa the browse lists look like. Subnet Browse Master List @@ -239,7 +242,7 @@ subnet 2 will still only see the servers on subnets 1 and 2, but not 3. Finally, the local master browser for subnet 2 (N2_B) will sync again with the domain master browser (N1_C) and will recieve the missing -server entries. Finally - and as a steady state (if no machines +server entries. Finally - and as a steady state (if no machines are removed or shut off) the browse lists will look like : Subnet Browse Master List @@ -273,36 +276,36 @@ names will not be removed from the network neighbourhood lists. 3) If one of the fragments is cut off from the WINS server, it will only be able to access servers on its local subnet, by using subnet-isolated -broadcast NetBIOS name resolution. The effects are similar to that of +broadcast NetBIOS name resolution. The effects are similar to that of losing access to a DNS server. Setting up a WINS server ======================== Either a Samba machine or a Windows NT Server machine may be set up -as a WINS server. To set a Samba machine to be a WINS server you must +as a WINS server. To set a Samba machine to be a WINS server you must add the following option to the smb.conf file on the selected machine : in the [globals] section add the line wins support = yes Versions of Samba previous to 1.9.17 had this parameter default to -yes. If you have any older versions of Samba on your network it is +yes. If you have any older versions of Samba on your network it is strongly suggested you upgrade to 1.9.17 or above, or at the very least set the parameter to 'no' on all these machines. Machines with "wins support = yes" will keep a list of all NetBIOS names registered with them, acting as a DNS for NetBIOS names. -You should set up only ONE wins server. Do NOT set the +You should set up only ONE wins server. Do NOT set the "wins support = yes" option on more than one Samba server. To set up a Windows NT Server as a WINS server you need to set up -the WINS service - see your NT documentation for details. Note that +the WINS service - see your NT documentation for details. Note that Windows NT WINS Servers can replicate to each other, allowing more -than one to be set up in a complex subnet environment. As Microsoft +than one to be set up in a complex subnet environment. As Microsoft refuse to document these replication protocols Samba cannot currently -participate in these replications. It is possible in the future that +participate in these replications. It is possible in the future that a Samba->Samba WINS replication protocol may be defined, in which case more than one Samba machine could be set up as a WINS server but currently only one Samba server should have the "wins support = yes" @@ -310,10 +313,10 @@ parameter set. After the WINS server has been configured you must ensure that all machines participating on the network are configured with the address -of this WINS server. If your WINS server is a Samba machine, fill in +of this WINS server. If your WINS server is a Samba machine, fill in the Samba machine IP address in the "Primary WINS Server" field of the "Control Panel->Network->Protocols->TCP->WINS Server" dialogs -in Windows 95 or Windows NT. To tell a Samba server the IP address +in Windows 95 or Windows NT. To tell a Samba server the IP address of the WINS server add the following line to the [global] section of all smb.conf files : @@ -323,14 +326,14 @@ where is either the DNS name of the WINS server machine or its IP address. Note that this line MUST NOT BE SET in the smb.conf file of the Samba -server acting as the WINS server itself. If you set both the +server acting as the WINS server itself. If you set both the "wins support = yes" option and the "wins server = " option then nmbd will fail to start. There are two possible scenarios for setting up cross subnet browsing. The first details setting up cross subnet browsing on a network containing Windows 95, Samba and Windows NT machines that are not configured as -part of a Windows NT Domain. The second details setting up cross subnet +part of a Windows NT Domain. The second details setting up cross subnet browsing on networks that contain NT Domains. Setting up Browsing in a WORKGROUP @@ -340,25 +343,23 @@ To set up cross subnet browsing on a network containing machines in up to be in a WORKGROUP, not an NT Domain you need to set up one Samba server to be the Domain Master Browser (note that this is *NOT* the same as a Primary Domain Controller, although in an NT Domain the -same machine plays both roles). The role of a Domain master browser is +same machine plays both roles). The role of a Domain master browser is to collate the browse lists from local master browsers on all the -subnets that have a machine participating in the workgroup. Without +subnets that have a machine participating in the workgroup. Without one machine configured as a domain master browser each subnet would be an isolated workgroup, unable to see any machines on any other -subnet. It is the presense of a domain master browser that makes +subnet. It is the presense of a domain master browser that makes cross subnet browsing possible for a workgroup. In an WORKGROUP environment the domain master browser must be a Samba server, and there must only be one domain master browser per -workgroup name (although the same Samba server can act as Domain -master browser for multiple workgroup names). To set up a Samba -server as a domain master browser set the following option in the -[global] section of the smb.conf file : +workgroup name. To set up a Samba server as a domain master browser, +set the following option in the [global] section of the smb.conf file : domain master = yes The domain master browser should also preferrably be the local master -browser for its own subnet. In order to achieve this set the following +browser for its own subnet. In order to achieve this set the following options in the [global] section of the smb.conf file : domain master = yes @@ -371,9 +372,9 @@ server, if you require. Next, you should ensure that each of the subnets contains a machine that can act as a local master browser for the -workgroup. Any NT machine should be able to do this, as will +workgroup. Any NT machine should be able to do this, as will Windows 95 machines (although these tend to get rebooted more -often, so it's not such a good idea to use these). To make a +often, so it's not such a good idea to use these). To make a Samba server a local master browser set the following options in the [global] section of the smb.conf file : @@ -387,7 +388,7 @@ or they will war with each other over which is to be the local master browser. The "local master" parameter allows Samba to act as a local master -browser. The "preferred master" causes nmbd to force a browser +browser. The "preferred master" causes nmbd to force a browser election on startup and the "os level" parameter sets Samba high enough so that it should win any browser elections. @@ -413,7 +414,7 @@ browser NetBIOS name (DOMAIN<1B>) with WINS instead of the PDC. For subnets other than the one containing the Windows NT PDC you may set up Samba servers as local master browsers as -described. To make a Samba server a local master browser set +described. To make a Samba server a local master browser set the following options in the [global] section of the smb.conf file : @@ -424,8 +425,8 @@ file : If you wish to have a Samba server fight the election with machines on the same subnet you may set the "os level" parameter to lower -levels. By doing this you can tune the order of machines that -will become local master browsers if they are running. For +levels. By doing this you can tune the order of machines that +will become local master browsers if they are running. For more details on this see the section "FORCING SAMBA TO BE THE MASTER" below. @@ -444,17 +445,17 @@ FORCING SAMBA TO BE THE MASTER ============================== Who becomes the "master browser" is determined by an election process -using broadcasts. Each election packet contains a number of parameters +using broadcasts. Each election packet contains a number of parameters which determine what precedence (bias) a host should have in the -election. By default Samba uses a very low precedence and thus loses +election. By default Samba uses a very low precedence and thus loses elections to just about anyone else. If you want Samba to win elections then just set the "os level" global -option in smb.conf to a higher number. It defaults to 0. Using 34 +option in smb.conf to a higher number. It defaults to 0. Using 34 would make it win all elections over every other system (except other samba systems!) -A "os level" of 2 would make it beat WfWg and Win95, but not NTAS. A +A "os level" of 2 would make it beat WfWg and Win95, but not NTAS. A NTAS domain controller uses level 32. The maximum os level is 255 @@ -487,9 +488,9 @@ MAKING SAMBA THE DOMAIN MASTER ============================== The domain master is responsible for collating the browse lists of -multiple subnets so that browsing can occur between subnets. You can +multiple subnets so that browsing can occur between subnets. You can make samba act as the domain master by setting "domain master = yes" -in smb.conf. By default it will not be a domain master. +in smb.conf. By default it will not be a domain master. Note that you should NOT set Samba to be the domain master for a workgroup that has the same name as an NT Domain. @@ -526,13 +527,13 @@ b) when a client receives a domain-wide browse list, and a user attempts to access a host in that list, it will contact the WINS server to resolve the NetBIOS name of that host. as long as that host has registered its NetBIOS name with the same WINS server, the user will - be able to see that host. + be able to see that host. NOTE ABOUT BROADCAST ADDRESSES ============================== If your network uses a "0" based broadcast address (for example if it -ends in a 0) then you will strike problems. Windows for Workgroups +ends in a 0) then you will strike problems. Windows for Workgroups does not seem to support a 0's broadcast and you will probably find that browsing and name lookups won't work. @@ -540,7 +541,7 @@ that browsing and name lookups won't work. MULTIPLE INTERFACES =================== -Samba now supports machines with multiple network interfaces. If you +Samba now supports machines with multiple network interfaces. If you have multiple interfaces then you will need to use the "interfaces" -option in smb.conf to configure them. See smb.conf(5) for details. +option in smb.conf to configure them. See smb.conf(5) for details. -- cgit v1.2.1 From 732aff735b996a3804ea4d3ca29b4b5f1302d663 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Oct 1997 03:49:29 +0000 Subject: remove { and } from the list of illegal characters in filenames. The CIFS3 spec does not list them as illegal. This allows things like the control panel icon to be placed on a Samba drive. --- source/smbd/mangle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/smbd/mangle.c b/source/smbd/mangle.c index a964f4a5c73..66e8233df28 100644 --- a/source/smbd/mangle.c +++ b/source/smbd/mangle.c @@ -602,7 +602,7 @@ static BOOL illegal_name(char *name) unsigned char *s; if (!initialised) { - char *ill = "*\\/?<>|\":{}"; + char *ill = "*\\/?<>|\":"; initialised = True; bzero((char *)illegal,256); -- cgit v1.2.1 From 849875f85196c0d3461b9466785c8f00ade0ec1f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 12 Oct 1997 23:51:46 +0000 Subject: updated the "comment =" entry a bit --- docs/manpages/smb.conf.5 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5 index 5c4ce3375fe..740c0921919 100644 --- a/docs/manpages/smb.conf.5 +++ b/docs/manpages/smb.conf.5 @@ -865,9 +865,11 @@ See also : "valid chars". client code page = 437 .SS comment (S) -This is a text field that is seen when a client does a net view to -list what shares are available. It will also be used when browsing is -fully supported. +This is a text field that is seen next to a share when a client does a +net view to list what shares are available. + +If you want to set the string that is displayed next to the machine +name then see the server string command. .B Default: No comment string -- cgit v1.2.1 From 366ec4de30c34b30a9c2a0a0525fcfaa1a6f4bee Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Oct 1997 01:53:20 +0000 Subject: Updated to stop problems with become_user. Jeremy (jallison@whistle.com) --- source/locking/locking.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/source/locking/locking.c b/source/locking/locking.c index b86ef76a2b8..db4990a7263 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -604,6 +604,7 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok { pstring fname; int fd; + int ret = True; *ptok = (share_lock_token)-1; @@ -640,6 +641,14 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok fd = (share_lock_token)open(fname,O_RDWR|O_CREAT,0666); #endif /* SECURE_SHARE_MODES */ + if(fd < 0) + { + DEBUG(0,("ERROR lock_share_entry: failed to open share file %s. Error was %s\n", + fname, strerror(errno))); + ret = False; + break; + } + /* At this point we have an open fd to the share mode file. Lock the first byte exclusively to signify a lock. */ if(fcntl_lock(fd, F_SETLKW, 0, 1, F_WRLCK) == False) @@ -647,7 +656,8 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok DEBUG(0,("ERROR lock_share_entry: fcntl_lock failed with %s\n", strerror(errno))); close(fd); - return False; + ret = False; + break; } /* @@ -665,25 +675,32 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok gotlock = True; } while(!gotlock); + /* + * We have to come here if any of the above calls fail + * as we don't want to return and leave ourselves running + * as root ! + */ + umask(old_umask); if(!become_user(cnum,Connections[cnum].vuid)) { DEBUG(0,("lock_share_entry: Can't become connected user!\n")); close(fd); - return False; + ret = False; } + /* We need to change directory back to the connection root. */ if (ChDir(Connections[cnum].connectpath) != 0) { DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n", Connections[cnum].connectpath, strerror(errno))); close(fd); - return False; + ret = False; } } *ptok = (share_lock_token)fd; - return True; + return ret; } /******************************************************************* -- cgit v1.2.1 From 0826e4b41b9fcbcdd8ff758c8b5b6da9ca28eb66 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Oct 1997 02:53:58 +0000 Subject: minor fixes to mangling and oplocks entries in man page --- docs/manpages/smb.conf.5 | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/docs/manpages/smb.conf.5 b/docs/manpages/smb.conf.5 index 740c0921919..b5fe0fd1a00 100644 --- a/docs/manpages/smb.conf.5 +++ b/docs/manpages/smb.conf.5 @@ -282,9 +282,9 @@ substitutions and other smb.conf options. .SS NAME MANGLING -Samba supports "name mangling" so that DOS and Windows clients can use -files that don't conform to the 8.3 format. It can also be set to adjust -the case of 8.3 format filenames. +Samba supports "name mangling" so that older DOS and Windows 3 clients +can use files that don't conform to the 8.3 format. It can also be set +to adjust the case of 8.3 format filenames. There are several options that control the way mangling is performed, and they are grouped here rather than listed separately. For the @@ -1206,12 +1206,11 @@ only one accessing the file and it will aggressively cache file data. With some oplock types the client may even cache file open/close operations. This can give enormous performance benefits. -Samba does not support opportunistic locks because they are very -difficult to do under Unix. Samba can fake them, however, by granting -a oplock whenever a client asks for one. This is controlled using the -smb.conf option "fake oplocks". If you set "fake oplocks = yes" then -you are telling the client that it may aggressively cache the file -data. +Samba does not support opportunistic locks in this release. Samba can +fake them, however, by granting a oplock whenever a client asks for +one. This is controlled using the smb.conf option "fake oplocks". If +you set "fake oplocks = yes" then you are telling the client that it +may aggressively cache the file data. By enabling this option on all read-only shares or shares that you know will only be accessed from one client at a time you will see a big -- cgit v1.2.1 From 78348cb8f8afe6454bd0e3a9f0b93b8c9c0b85b9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 14 Oct 1997 09:15:58 +0000 Subject: add become_root()/unbecome_root() calls. These should be used around regions of the code that need root privilages but which normally don't have them (ie. when processing most SMBs). These functions can optionally save/restore the current working directory as well updated several places in the code that previously used unbecome_user() to achieve the same thing to now use become_root() and unbecome_root() changed close_file() to take an additional argument which says whether this is a normal SMBclose type call or a close that resulted from some other action, such as the close of a connection. If it is a abnormal close then don't use magic scripts or print files. changed sys_utime() to ignore any attempt to set the modification time to 0 or -1. We've had reports that files have had their time set to 0 so this should catch those. --- source/include/proto.h | 4 ++- source/lib/system.c | 13 ++++++-- source/locking/locking.c | 65 ++++++++++++------------------------- source/smbd/ipc.c | 5 ++- source/smbd/pipes.c | 4 +-- source/smbd/reply.c | 24 +++++++------- source/smbd/server.c | 23 ++++++++----- source/smbd/trans2.c | 4 +-- source/smbd/uid.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++- 9 files changed, 152 insertions(+), 74 deletions(-) diff --git a/source/include/proto.h b/source/include/proto.h index ffa2f251cca..d7cbc4cc4c4 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -705,7 +705,7 @@ int fd_attempt_open(char *fname, int flags, int mode); void fd_attempt_reopen(char *fname, int mode, file_fd_struct *fd_ptr); int fd_attempt_close(file_fd_struct *fd_ptr); void sync_file(int fnum); -void close_file(int fnum); +void close_file(int fnum, int normal_close); BOOL check_file_sharing(int cnum,char *fname); void open_file_shared(int fnum,int cnum,char *fname,int share_mode,int ofun, int mode,int *Access,int *action); @@ -847,6 +847,8 @@ BOOL become_guest(void); BOOL become_user(int cnum, uint16 vuid); BOOL unbecome_user(void ); int smbrun(char *cmd,char *outfile,BOOL shared); +void become_root(int save_dir) ; +void unbecome_root(int restore_dir); /*The following definitions come from username.c */ diff --git a/source/lib/system.c b/source/lib/system.c index df24691512f..b149ccb4b98 100644 --- a/source/lib/system.c +++ b/source/lib/system.c @@ -194,14 +194,23 @@ now for utime() ********************************************************************/ int sys_utime(char *fname,struct utimbuf *times) { - return(utime(dos_to_unix(fname,False),times)); + /* if the modtime is 0 or -1 then ignore the call and + return success */ + if (times->modtime == (time_t)0 || times->modtime == (time_t)-1) + return 0; + + /* if the access time is 0 or -1 then set it to the modtime */ + if (times->actime == (time_t)0 || times->actime == (time_t)-1) + times->actime = times->modtime; + + return(utime(dos_to_unix(fname,False),times)); } + /********************************************************* for rename across filesystems Patch from Warren Birnbaum **********************************************************/ - static int copy_reg (const char *source, const char *dest) { diff --git a/source/locking/locking.c b/source/locking/locking.c index db4990a7263..461ad5aef0b 100644 --- a/source/locking/locking.c +++ b/source/locking/locking.c @@ -611,10 +611,12 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok if(!share_name(cnum, dev, inode, fname)) return False; + /* we need to do this as root */ + become_root(0); + { int old_umask; BOOL gotlock = False; - unbecome_user(); old_umask = umask(0); /* @@ -675,31 +677,14 @@ BOOL lock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token *ptok gotlock = True; } while(!gotlock); - /* - * We have to come here if any of the above calls fail - * as we don't want to return and leave ourselves running - * as root ! - */ - umask(old_umask); - if(!become_user(cnum,Connections[cnum].vuid)) - { - DEBUG(0,("lock_share_entry: Can't become connected user!\n")); - close(fd); - ret = False; - } - - /* We need to change directory back to the connection root. */ - if (ChDir(Connections[cnum].connectpath) != 0) - { - DEBUG(0,("lock_share_entry: Can't change directory to %s (%s)\n", - Connections[cnum].connectpath, strerror(errno))); - close(fd); - ret = False; - } } *ptok = (share_lock_token)fd; + + /* return to our previous privilage level */ + unbecome_root(0); + return ret; } @@ -727,31 +712,21 @@ BOOL unlock_share_entry(int cnum, uint32 dev, uint32 inode, share_lock_token tok /******************************************************************* Force a share file to be deleted. ********************************************************************/ - static int delete_share_file( int cnum, char *fname ) { - unbecome_user(); - if(unlink(fname) != 0) - { - DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n", - fname, strerror(errno))); - } - - DEBUG(5,("delete_share_file: Deleted share file %s\n", fname)); - - if(!become_user(cnum,Connections[cnum].vuid)) - { - DEBUG(0,("delete_share_file: Can't become connected user!\n")); - return -1; - } - /* We need to change directory back to the connection root. */ - if (ChDir(Connections[cnum].connectpath) != 0) - { - DEBUG(0,("delete_share_file: Can't change directory to %s (%s)\n", - Connections[cnum].connectpath, strerror(errno))); - return -1; - } - return 0; + /* the share file could be owned by anyone, so do this as root */ + become_root(0); + + if(unlink(fname) != 0) { + DEBUG(0,("delete_share_file: Can't delete share file %s (%s)\n", + fname, strerror(errno))); + } else { + DEBUG(5,("delete_share_file: Deleted share file %s\n", fname)); + } + + unbecome_root(0); + + return 0; } /******************************************************************* diff --git a/source/smbd/ipc.c b/source/smbd/ipc.c index a0a4ec8fc73..1d7ee375d3f 100644 --- a/source/smbd/ipc.c +++ b/source/smbd/ipc.c @@ -1601,13 +1601,14 @@ static BOOL api_PrintJobInfo(int cnum,uint16 vuid,char *param,char *data, name[l] = 0; DEBUG(3,("Setting print name to %s\n",name)); + + become_root(1); for (i=0;ifd,&sbuf) != 0) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -149,7 +149,7 @@ int reply_open_pipe_and_X(char *inbuf,char *outbuf,int length,int bufsize) fmode = dos_mode(cnum,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 7925add45f3..ffa80aac870 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -1138,7 +1138,7 @@ int reply_open(char *inbuf,char *outbuf) } if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1148,7 +1148,7 @@ int reply_open(char *inbuf,char *outbuf) if (fmode & aDIR) { DEBUG(3,("attempt to open a directory %s\n",fname)); - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1229,7 +1229,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) } if (fstat(Files[fnum].fd_ptr->fd,&sbuf) != 0) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1237,7 +1237,7 @@ int reply_open_and_X(char *inbuf,char *outbuf,int length,int bufsize) fmode = dos_mode(cnum,fname,&sbuf); mtime = sbuf.st_mtime; if (fmode & aDIR) { - close_file(fnum); + close_file(fnum, 0); return(ERROR(ERRDOS,ERRnoaccess)); } @@ -1277,7 +1277,7 @@ int reply_ulogoffX(char *inbuf,char *outbuf,int length,int bufsize) int i; for (i=0;iuid && Files[i].open) { - close_file(i); + close_file(i, 0); } } @@ -2190,7 +2190,7 @@ int reply_close(char *inbuf,char *outbuf) /* try and set the date */ set_filetime(Files[fnum].name,mtime); - close_file(fnum); + close_file(fnum, 1); /* We have a cached error */ if(eclass || err) @@ -2237,7 +2237,7 @@ int reply_writeclose(char *inbuf,char *outbuf) set_filetime(Files[fnum].name,mtime); - close_file(fnum); + close_file(fnum, 1); DEBUG(3,("%s writeclose fnum=%d cnum=%d num=%d wrote=%d (numopen=%d)\n", timestring(),fnum,cnum,numtowrite,nwritten, @@ -2468,7 +2468,7 @@ int reply_printclose(char *inbuf,char *outbuf) if (!CAN_PRINT(cnum)) return(ERROR(ERRDOS,ERRnoaccess)); - close_file(fnum); + close_file(fnum, 1); DEBUG(3,("%s printclose fd=%d fnum=%d cnum=%d\n",timestring(),Files[fnum].fd_ptr->fd,fnum,cnum)); @@ -3040,14 +3040,14 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, fnum2 = find_free_file(); if (fnum2<0) { - close_file(fnum1); + close_file(fnum1, 0); return(False); } open_file_shared(fnum2,cnum,dest,(DENY_NONE<<4)|1, ofun,st.st_mode,&Access,&action); if (!Files[fnum2].open) { - close_file(fnum1); + close_file(fnum1, 0); return(False); } @@ -3058,8 +3058,8 @@ static BOOL copy_file(char *src,char *dest1,int cnum,int ofun, if (st.st_size) ret = transfer_file(Files[fnum1].fd_ptr->fd,Files[fnum2].fd_ptr->fd,st.st_size,NULL,0,0); - close_file(fnum1); - close_file(fnum2); + close_file(fnum1, 0); + close_file(fnum2, 0); return(ret == st.st_size); } diff --git a/source/smbd/server.c b/source/smbd/server.c index 8e1bc152ffd..3bfd5bbbf40 100644 --- a/source/smbd/server.c +++ b/source/smbd/server.c @@ -1348,8 +1348,13 @@ static void check_magic(int fnum,int cnum) /**************************************************************************** close a file - possibly invalidating the read prediction + +If normal_close is 1 then this came from a normal SMBclose (or equivalent) +operation otherwise it came as the result of some other operation such as +the closing of the connection. In the latter case printing and +magic scripts are not run ****************************************************************************/ -void close_file(int fnum) +void close_file(int fnum, int normal_close) { files_struct *fs_p = &Files[fnum]; int cnum = fs_p->cnum; @@ -1386,11 +1391,12 @@ void close_file(int fnum) unlock_share_entry( cnum, dev, inode, token); /* NT uses smbclose to start a print - weird */ - if (fs_p->print_file) + if (normal_close && fs_p->print_file) print_file(fnum); /* check for magic scripts */ - check_magic(fnum,cnum); + if (normal_close) + check_magic(fnum,cnum); DEBUG(2,("%s %s closed file %s (numopen=%d)\n", timestring(),Connections[cnum].user,fs_p->name, @@ -1510,7 +1516,7 @@ static void truncate_unless_locked(int fnum, int cnum, share_lock_token token, if (*share_locked && lp_share_modes(SNUM(cnum))) unlock_share_entry( cnum, Files[fnum].fd_ptr->dev, Files[fnum].fd_ptr->inode, token); - close_file(fnum); + close_file(fnum, 0); /* Share mode no longer locked. */ *share_locked = False; errno = EACCES; @@ -3203,7 +3209,7 @@ static void close_open_files(int cnum) int i; for (i=0;i 0) { + if (setgroups(current_user_saved.ngroups, + current_user_saved.groups)<0) + DEBUG(0,("ERROR: setgroups call failed!\n")); + } +#endif + + /* now restore our uid */ + if (!become_uid(current_user_saved.uid)) { + DEBUG(0,("ERROR: Failed to restore uid\n")); + exit_server("Failed to restore uid"); + } + + if (restore_dir) + ChDir(become_root_dir); + + current_user = current_user_saved; + + become_root_depth = 0; +} + + + -- cgit v1.2.1 From 676c443d21ff8f5e659e933ee3e22cd0e79c50f3 Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Tue, 14 Oct 1997 13:18:07 +0000 Subject: docs/DIAGNOSIS.txt: Added comments up front about "your server is being unfriendly" and need to check IP name resolution. --- docs/textdocs/DIAGNOSIS.txt | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/docs/textdocs/DIAGNOSIS.txt b/docs/textdocs/DIAGNOSIS.txt index 11eb91b2ff8..18259ecc94f 100644 --- a/docs/textdocs/DIAGNOSIS.txt +++ b/docs/textdocs/DIAGNOSIS.txt @@ -1,5 +1,5 @@ Contributor: Andrew Tridgell -Updated: June 27, 1997 +Updated: October 14, 1997 Subject: DIAGNOSING YOUR SAMBA SERVER =========================================================================== @@ -44,6 +44,15 @@ smb.conf. I will assume this share is called "tmp". You can add a THESE TESTS ASSUME VERSION 1.9.16 OR LATER OF THE SAMBA SUITE. SOME COMMANDS SHOWN DID NOT EXIST IN EARLIER VERSIONS +Please pay attention to the error messages you receive. If any error message +reports that your server is being unfriendly you should first check that you +IP name resolution is correctly set up. eg: Make sure your /etc/resolv.conf +file points to name servers that really do exist. + +Also, if you do not have DNS server access for name resolution please check +that the settings for your smb.conf file results in "dns proxy = no". The +best way to check this is with "testparm smb.conf" + TEST 1: ------- @@ -53,7 +62,7 @@ In the directory in which you store your smb.conf file, run the command configuration file is faulty. Note: Your smb.conf file may be located in: /etc - or in: /usr/local/samba/lib + Or in: /usr/local/samba/lib TEST 2: @@ -254,7 +263,10 @@ Still having troubles? ---------------------- Try the mailing list or newsgroup, or use the tcpdump-smb utility to -sniff the problem. +sniff the problem. The official samba mailing list can be reached at +samba@samba.anu.edu.au. To find out more about samba and how to +subscribe to the mailing list check out the samba web page at + http://samba.anu.edu.au/samba Also look at the other docs in the Samba package! -- cgit v1.2.1 From 4200f5a328e1934d4d9cbc4e069e723b639a49db Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 15 Oct 1997 01:34:04 +0000 Subject: Added #ifdef'ed code with BIND_LOCAL_OUTPUT_SOCKET that causes optput sockets to be bound to the same local address as input ones are. Jeremy (jallison@whistle.com) --- source/lib/util.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/source/lib/util.c b/source/lib/util.c index 459745b8b14..54b2dc08ac8 100644 --- a/source/lib/util.c +++ b/source/lib/util.c @@ -3035,8 +3035,26 @@ int open_socket_out(int type, struct in_addr *addr, int port ,int timeout) if (res == -1) { DEBUG(0,("socket error\n")); return -1; } - if (type != SOCK_STREAM) return(res); +#ifdef BIND_LOCAL_OUTPUT_SOCKET + { + struct sockaddr_in sock_in; + /* Bind the local part of this socket to the address + given in the socket address parameter. */ + + bzero((char *)&sock_in,sizeof(sock_in)); + putip((char *)&sock_in.sin_addr,(char *)interpret_addr2(lp_socket_address())); + sock_in.sin_port = 0; + sock_in.sin_family = PF_INET; + + if (bind(res, (struct sockaddr * ) &sock_in,sizeof(sock_in)) < 0) + DEBUG(0,("Failed to bind local socket address for output socket. Error was %s\n", + strerror(errno))); + } +#endif /* BIND_LOCAL_OUTPUT_SOCKET */ + + if (type != SOCK_STREAM) return(res); + bzero((char *)&sock_out,sizeof(sock_out)); putip((char *)&sock_out.sin_addr,(char *)addr); -- cgit v1.2.1 From 128a4422baa2f642fca0a6a19756136d57f5d37c Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 15 Oct 1997 01:34:56 +0000 Subject: Updated for 1.9.17p3 release. Jeremy (jallison@whistle,com): --- WHATSNEW.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WHATSNEW.txt b/WHATSNEW.txt index b3aa7d78a17..3ce008ff66c 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,4 +1,4 @@ - WHATS NEW IN 1.9.17p2 - October 13th 1997 + WHATS NEW IN 1.9.17p2 - October 14th 1997 =========================================== Update release: Samba - version 1.9.17p3. @@ -11,7 +11,7 @@ for all current bug-fixes. Here are a list of the fixes in this release (the fixes introduced between 1.9.17p2 and 1.9.17p3) : -1). Truncation of long browse lists. +1). Removed truncation problem with long browse lists. 2). Crash bug when dead share mode memory entries need removing. 3). Race condition in slow share mode code. 4). Potential buffer overflow from password server. @@ -24,6 +24,8 @@ introduced between 1.9.17p2 and 1.9.17p3) : 10). Wrapping log file causes incorrect errors to be returned to the clients. 11). Crash fix for nmbd Get_Hostbyname bad return. +12). 'become_root' 'unbecome_root' added to fix changing uid problems. +13). No magic scripts or printing done on exceptional file close problems. Reporting bugs -------------- -- cgit v1.2.1 From a173a1495c50b5ad1f6b47710cf4b4a7a2226b46 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 15 Oct 1997 01:38:13 +0000 Subject: preparing for release of 1.9.17p3 --- source/include/version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/include/version.h b/source/include/version.h index 76ccca122c6..7bea7836bc6 100644 --- a/source/include/version.h +++ b/source/include/version.h @@ -1 +1 @@ -#define VERSION "1.9.17p2" +#define VERSION "1.9.17p3" -- cgit v1.2.1