From 59d07445b61e26321e3a1770c13756ac5948aabb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Jul 1998 21:23:59 +0000 Subject: loadparm.c: With apologies to Charlton Heston and Pierre Boule. "You damn fools, you finally did it". Changed default security mode to be security=user. Yes this is a big (although small in code) change. It's something we've been discussing for a while, to finally wean people off the legacy security=share mode which is *never* what you want. Jeremy. nmbd_incomingrequests.c: Bug fix for nmbd core dumps caused by overrun. Found by . nttrans.c: More NT smb stuff. reply.c: Unlink will overwrite an existing file. Well you learn something new about POSIX every day. :-). server.c: Tidyup unreadable code. smbpasswd.c: Code to allow -U remote_username to allow ordinary users to change remote passwords if their NT username is different from their UNIX username. Patch from . Jeremy. (This used to be commit 4eccb47cfb3c8907a6558b6ea9a02b0184458e34) --- source3/nmbd/nmbd_incomingrequests.c | 2 +- source3/param/loadparm.c | 2 +- source3/smbd/nttrans.c | 3 +- source3/smbd/reply.c | 26 +++--- source3/smbd/server.c | 176 +++++++++++++++++------------------ source3/utils/smbpasswd.c | 25 +++-- 6 files changed, 119 insertions(+), 115 deletions(-) diff --git a/source3/nmbd/nmbd_incomingrequests.c b/source3/nmbd/nmbd_incomingrequests.c index 790d19d609..3c9438ace3 100644 --- a/source3/nmbd/nmbd_incomingrequests.c +++ b/source3/nmbd/nmbd_incomingrequests.c @@ -420,7 +420,7 @@ subnet %s - name not found.\n", namestr(&nmb->question.question_name), /* We don't send any stats as they could be used to attack the protocol. */ - bzero(buf,64); + bzero(buf,46); buf += 46; diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 820479ae65..d6ec24ab5b 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -785,7 +785,7 @@ static void init_globals(void) Globals.deadtime = 0; Globals.max_log_size = 5000; Globals.maxprotocol = PROTOCOL_NT1; - Globals.security = SEC_SHARE; + Globals.security = SEC_USER; Globals.bEncryptPasswords = False; Globals.bUpdateEncrypt = False; Globals.bReadRaw = True; diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index fa47bc7a17..65f2b0274e 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -766,7 +766,8 @@ static int call_nt_transact_rename(char *inbuf, char *outbuf, int bufsize, int c StrnCpy(new_name,params+4,fname_len); new_name[fname_len] = '\0'; - outsize = rename_internals(inbuf, outbuf, Files[fnum].name, newname, replace_if_exists); + outsize = rename_internals(inbuf, outbuf, Files[fnum].name, + newname, replace_if_exists); if(outsize == 0) { /* * Rename was successful. diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index cb659e3ef9..07b72738c5 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -3258,21 +3258,21 @@ int rename_internals(char *inbuf, char *outbuf, char *name, char *newname, BOOL if(replace_if_exists) { /* - * NT SMB specific flag - we must remove a target - * file with the same name before continuing. + * NT SMB specific flag - rename can overwrite + * file with the same name so don't check for + * file_exist(). */ if(resolve_wildcards(directory,newname) && can_rename(directory,cnum) && - file_exist(newname,NULL)) { - sys_unlink(newname); - } - } - - if (resolve_wildcards(directory,newname) && - can_rename(directory,cnum) && - !file_exist(newname,NULL) && !sys_rename(directory,newname)) - count++; + count++; + } else { + if (resolve_wildcards(directory,newname) && + can_rename(directory,cnum) && + !file_exist(newname,NULL) && + !sys_rename(directory,newname)) + count++; + } DEBUG(3,("rename_internals: %s doing rename on %s -> %s\n",(count != 0) ? "succeeded" : "failed", directory,newname)); @@ -3319,9 +3319,7 @@ int rename_internals(char *inbuf, char *outbuf, char *name, char *newname, BOOL continue; } - if (replace_if_exists && file_exist(destname,NULL)) { - sys_unlink(destname); - } else if(file_exist(destname,NULL)) { + if (!replace_if_exists && file_exist(destname,NULL)) { DEBUG(6,("file_exist %s\n", destname)); error = 183; continue; diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 374c41c1f5..154f8ed93e 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -4787,126 +4787,126 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize /* make sure this is an SMB packet */ if (strncmp(smb_base(inbuf),"\377SMB",4) != 0) - { - DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf))); - return(-1); - } + { + DEBUG(2,("Non-SMB packet of length %d\n",smb_len(inbuf))); + return(-1); + } for (match=0;matchrequested_name); - } + /* + * Ensure the correct username is in sesssetup_user. + * This is a really ugly bugfix for problems with + * multiple session_setup_and_X's being done and + * allowing %U and %G substitutions to work correctly. + * There is a reason this code is done here, don't + * move it unless you know what you're doing... :-). + * JRA. + */ + if(session_tag != last_session_tag ) { + user_struct *vuser = NULL; + + last_session_tag = session_tag; + if(session_tag != UID_FIELD_INVALID) + vuser = get_valid_user_struct(session_tag); + if(vuser != NULL) + pstrcpy( sesssetup_user, vuser->requested_name); + } - /* does this protocol need to be run as root? */ - if (!(flags & AS_USER)) - unbecome_user(); + /* does this protocol need to be run as root? */ + if (!(flags & AS_USER)) + unbecome_user(); - /* does this protocol need to be run as the connected user? */ - if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) { - if (flags & AS_GUEST) - flags &= ~AS_USER; - else - return(ERROR(ERRSRV,ERRinvnid)); - } - /* this code is to work around a bug is MS client 3 without - introducing a security hole - it needs to be able to do - print queue checks as guest if it isn't logged in properly */ - if (flags & AS_USER) - flags &= ~AS_GUEST; + /* does this protocol need to be run as the connected user? */ + if ((flags & AS_USER) && !become_user(&Connections[cnum], cnum,session_tag)) { + if (flags & AS_GUEST) + flags &= ~AS_USER; + else + return(ERROR(ERRSRV,ERRinvnid)); + } + /* this code is to work around a bug is MS client 3 without + introducing a security hole - it needs to be able to do + print queue checks as guest if it isn't logged in properly */ + if (flags & AS_USER) + flags &= ~AS_GUEST; - /* does it need write permission? */ - if ((flags & NEED_WRITE) && !CAN_WRITE(cnum)) - return(ERROR(ERRSRV,ERRaccess)); + /* does it need write permission? */ + if ((flags & NEED_WRITE) && !CAN_WRITE(cnum)) + return(ERROR(ERRSRV,ERRaccess)); - /* ipc services are limited */ - if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC)) - return(ERROR(ERRSRV,ERRaccess)); + /* ipc services are limited */ + if (IS_IPC(cnum) && (flags & AS_USER) && !(flags & CAN_IPC)) + return(ERROR(ERRSRV,ERRaccess)); - /* load service specific parameters */ - if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False)) - return(ERROR(ERRSRV,ERRaccess)); + /* load service specific parameters */ + if (OPEN_CNUM(cnum) && !become_service(cnum,(flags & AS_USER)?True:False)) + return(ERROR(ERRSRV,ERRaccess)); - /* does this protocol need to be run as guest? */ - if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1))) - return(ERROR(ERRSRV,ERRaccess)); + /* does this protocol need to be run as guest? */ + if ((flags & AS_GUEST) && (!become_guest() || !check_access(-1))) + return(ERROR(ERRSRV,ERRaccess)); - last_inbuf = inbuf; + last_inbuf = inbuf; - outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize); - } - else - { - outsize = reply_unknown(inbuf,outbuf); - } + outsize = smb_messages[match].fn(inbuf,outbuf,size,bufsize); + } + else + { + outsize = reply_unknown(inbuf,outbuf); } + } #if PROFILING GetTimeOfDay(&msg_end_time); if (!(smb_messages[match].flags & TIME_INIT)) - { - smb_messages[match].time = 0; - smb_messages[match].flags |= TIME_INIT; - } + { + smb_messages[match].time = 0; + smb_messages[match].flags |= TIME_INIT; + } { unsigned long this_time = (msg_end_time.tv_sec - msg_start_time.tv_sec)*1e6 + - (msg_end_time.tv_usec - msg_start_time.tv_usec); + (msg_end_time.tv_usec - msg_start_time.tv_usec); smb_messages[match].time += this_time; total_time += this_time; } DEBUG(2,("TIME %s %d usecs %g pct\n", - smb_fn_name(type),smb_messages[match].time, - (100.0*smb_messages[match].time) / total_time)); + smb_fn_name(type),smb_messages[match].time, + (100.0*smb_messages[match].time) / total_time)); #endif return(outsize); diff --git a/source3/utils/smbpasswd.c b/source3/utils/smbpasswd.c index c9742fc498..f9b9506297 100644 --- a/source3/utils/smbpasswd.c +++ b/source3/utils/smbpasswd.c @@ -33,9 +33,9 @@ static void usage(char *name, BOOL is_root) { if(is_root) fprintf(stderr, "Usage is : %s [-D DEBUGLEVEL] [-a] [-d] [-m] [-n] [username] [password]\n\ -%s: [-R ] [-D DEBUGLEVEL] [-j DOMAINNAME] [-r machine] [username] [password]\n%s: [-h]\n", name, name, name); +%s: [-R ] [-D DEBUGLEVEL] [-j DOMAINNAME] [-r machine] [-U remote_username] [username] [password]\n%s: [-h]\n", name, name, name); else - fprintf(stderr, "Usage is : %s [-h] [-D DEBUGLEVEL] [-r machine] [password]\n", name); + fprintf(stderr, "Usage is : %s [-h] [-D DEBUGLEVEL] [-r machine] [-U remote_username] [password]\n", name); exit(1); } @@ -134,6 +134,7 @@ int main(int argc, char **argv) int err; BOOL is_root = False; pstring user_name; + BOOL remote_user_name = False; char *remote_machine = NULL; BOOL add_user = False; BOOL got_new_pass = False; @@ -201,7 +202,7 @@ int main(int argc, char **argv) is_root = (real_uid == 0); - while ((ch = getopt(argc, argv, "adhmnj:r:R:D:")) != EOF) { + while ((ch = getopt(argc, argv, "adhmnj:r:R:D:U:")) != EOF) { switch(ch) { case 'a': if(is_root) @@ -250,6 +251,10 @@ int main(int argc, char **argv) } else usage(prog_name, is_root); break; + case 'U': + remote_user_name = True; + pstrcpy(user_name, optarg); + break; case 'h': default: usage(prog_name, is_root); @@ -259,6 +264,11 @@ int main(int argc, char **argv) argc -= optind; argv += optind; + if (!is_root && remote_user_name && !remote_machine) { + fprintf(stderr, "%s: You can only use -U with -r.\n", prog_name); + usage(prog_name, False); + } + /* * Ensure add_user and either remote machine or join domain are * not both set. @@ -314,12 +324,7 @@ int main(int argc, char **argv) } } - /* - * Setup the pwd struct to point to known - * values for a machine account (it doesn't - * exist in /etc/passwd). - */ - if((pwd = Get_Pwnam(user_name, True)) == NULL) { + if(!remote_machine && ((pwd = Get_Pwnam(user_name, True)) == NULL)) { fprintf(stderr, "%s: User \"%s\" was not found in system password file.\n", prog_name, user_name); exit(1); @@ -344,7 +349,7 @@ int main(int argc, char **argv) got_new_pass = True; } - if((pwd = getpwuid(real_uid)) != NULL) + if(!remote_user_name && ((pwd = getpwuid(real_uid)) != NULL)) pstrcpy( user_name, pwd->pw_name); /* -- cgit