From 0e8fd3398771da2f016d72830179507f3edda51b Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 4 May 1996 07:50:46 +0000 Subject: Initial version imported to CVS (This used to be commit 291551d80711daab7b7581720bcd9a08d6096517) --- source3/smbd/password.c | 1416 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1416 insertions(+) create mode 100644 source3/smbd/password.c (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c new file mode 100644 index 0000000000..87c1fef94c --- /dev/null +++ b/source3/smbd/password.c @@ -0,0 +1,1416 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Password and authentication handling + Copyright (C) Andrew Tridgell 1992-1995 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" +#include "loadparm.h" + +extern int DEBUGLEVEL; +extern int Protocol; + +/* users from session setup */ +static pstring session_users=""; + +/* these are kept here to keep the string_combinations function simple */ +static char this_user[100]=""; +static char this_salt[100]=""; +static char this_crypted[100]=""; + +#ifdef SMB_PASSWD +/* Data to do lanman1/2 password challenge. */ +static unsigned char saved_challenge[8]; +static BOOL challenge_sent=False; + +/******************************************************************* +Get the next challenge value - no repeats. +********************************************************************/ +void generate_next_challenge(char *challenge) +{ + extern void E1(char *,char *,char *); + static int counter = 0; + struct timeval tval; + int v1,v2; + GetTimeOfDay(&tval); + v1 = (counter++) + getpid() + tval.tv_sec; + v2 = (counter++) * getpid() + tval.tv_usec; + SIVAL(challenge,0,v1); + SIVAL(challenge,4,v2); + E1(challenge,"SAMBA",saved_challenge); + memcpy(challenge,saved_challenge,8); + challenge_sent = True; +} + +/******************************************************************* +set the last challenge sent, usually from a password server +********************************************************************/ +BOOL set_challenge(char *challenge) +{ + memcpy(saved_challenge,challenge,8); + challenge_sent = True; + return(True); +} + +/******************************************************************* +get the last challenge sent +********************************************************************/ +BOOL last_challenge(char *challenge) +{ + if (!challenge_sent) return(False); + memcpy(challenge,saved_challenge,8); + return(True); +} +#endif + +/* this holds info on user ids that are already validated for this VC */ +static user_struct *validated_users = NULL; +static int num_validated_users = 0; + +/**************************************************************************** +check if a uid has been validated, and return an index if it has. -1 if not +****************************************************************************/ +int valid_uid(int uid) +{ + int i; + if (uid == -1) return(-1); + + for (i=0;iuid = -1; + vuser->gid = -1; + vuser->user_ngroups = 0; + if(vuser->user_groups && + (vuser->user_groups != (gid_t *)vuser->user_igroups)) + free(vuser->user_groups); + vuser->user_groups = NULL; + if(vuser->user_igroups) + free(vuser->user_igroups); + vuser->user_igroups = NULL; + } +} + + +/**************************************************************************** +return a validated username +****************************************************************************/ +char *validated_username(int vuid) +{ + return(validated_users[vuid].name); +} + +/**************************************************************************** +register a uid/name pair as being valid and that a valid password +has been given. +****************************************************************************/ +void register_uid(int uid,int gid, char *name,BOOL guest) +{ + user_struct *vuser; + + if (valid_uid(uid) >= 0) + return; + validated_users = (user_struct *)Realloc(validated_users, + sizeof(user_struct)* + (num_validated_users+1)); + + if (!validated_users) + { + DEBUG(0,("Failed to realloc users struct!\n")); + return; + } + + vuser = &validated_users[num_validated_users]; + vuser->uid = uid; + vuser->gid = gid; + vuser->guest = guest; + strcpy(vuser->name,name); + + vuser->user_ngroups = 0; + vuser->user_groups = NULL; + vuser->user_igroups = NULL; + + /* Find all the groups this uid is in and store them. + Used by become_user() */ + setup_groups(name,uid,gid, + &vuser->user_ngroups, + &vuser->user_igroups, + &vuser->user_groups); + + DEBUG(3,("uid %d registered to name %s\n",uid,name)); + + num_validated_users++; +} + + +/**************************************************************************** +add a name to the session users list +****************************************************************************/ +void add_session_user(char *user) +{ + fstring suser; + StrnCpy(suser,user,sizeof(suser)-1); + + if (!Get_Pwnam(suser,True)) return; + + if (suser && *suser && !in_list(suser,session_users,False)) + { + if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring)) + DEBUG(1,("Too many session users??\n")); + else + { + strcat(session_users," "); + strcat(session_users,suser); + } + } +} + + +#ifdef NO_GETSPNAM +/* a fake shadow password routine which just fills a fake spwd struct + * with the sp_pwdp field. (sreiz@aie.nl) + */ +static struct spwd *getspnam(char *username) /* fake shadow password routine */ +{ + FILE *f; + char line[1024]; + static char pw[20]; + static struct spwd static_spwd; + + static_spwd.sp_pwdp=0; + if (!(f=fopen("/etc/master.passwd", "r"))) + return 0; + while (fgets(line, 1024, f)) { + if (!strncmp(line, username, strlen(username)) && + line[strlen(username)]==':') { /* found entry */ + char *p, *q; + + p=line+strlen(username)+1; + if ((q=strchr(p, ':'))) { + *q=0; + if (q-p+1>20) + break; + strcpy(pw, p); + static_spwd.sp_pwdp=pw; + } + break; + } + } + fclose(f); + if (static_spwd.sp_pwdp) + return &static_spwd; + return 0; +} +#endif + + +#ifdef OSF1_ENH_SEC +/**************************************************************************** +an enhanced crypt for OSF1 +****************************************************************************/ +static char *osf1_bigcrypt(char *password,char *salt1) +{ + static char result[AUTH_MAX_PASSWD_LENGTH] = ""; + char *p1; + char *p2=password; + char salt[3]; + int i; + int parts = strlen(password) / AUTH_CLEARTEXT_SEG_CHARS; + if (strlen(password)%AUTH_CLEARTEXT_SEG_CHARS) + parts++; + + StrnCpy(salt,salt1,2); + StrnCpy(result,salt1,2); + + for (i=0; iufld.fd_slogin = tz; + mypasswd->ufld.fd_nlogins = 0; + + putprpwnam(user,mypasswd); + + DEBUG(3,("Update protected database for Account %s after succesful connection\n",user)); + } + else + { + mypasswd->ufld.fd_ulogin = tz; + mypasswd->ufld.fd_nlogins = mypasswd->ufld.fd_nlogins + 1; + if ( mypasswd->ufld.fd_max_tries != 0 && mypasswd->ufld.fd_nlogins > mypasswd->ufld.fd_max_tries ) + { + mypasswd->uflg.fg_lock = 0; + DEBUG(3,("Account is disabled -- see Account Administrator.\n")); + } + putprpwnam ( user , mypasswd ); + DEBUG(3,("Update protected database for Account %s after refusing connection\n",user)); + } +#else + DEBUG(6,("Updated database with %s %s\n",user,BOOLSTR(result))); +#endif +} + + +#ifdef AFS_AUTH +/******************************************************************* +check on AFS authentication +********************************************************************/ +static BOOL afs_auth(char *this_user,char *password) +{ + long password_expires = 0; + char *reason; + + /* For versions of AFS prior to 3.3, this routine has few arguments, */ + /* but since I can't find the old documentation... :-) */ + setpag(); + if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG, + this_user, + (char *) 0, /* instance */ + (char *) 0, /* cell */ + password, + 0, /* lifetime, default */ + &password_expires, /*days 'til it expires */ + 0, /* spare 2 */ + &reason) == 0) + return(True); + return(False); +} +#endif + + +#ifdef DFS_AUTH + +sec_login_handle_t my_dce_sec_context; +int dcelogin_atmost_once = 0; + +/******************************************************************* +check on a DCE/DFS authentication +********************************************************************/ +static BOOL dfs_auth(char *this_user,char *password) +{ + error_status_t err; + int err2; + int prterr; + boolean32 password_reset; + sec_passwd_rec_t my_dce_password; + sec_login_auth_src_t auth_src = sec_login_auth_src_network; + unsigned char dce_errstr[dce_c_error_string_len]; + + /* + * We only go for a DCE login context if the given password + * matches that stored in the local password file.. + * Assumes local passwd file is kept in sync w/ DCE RGY! + */ + + if (!strcmp((char *)crypt(password,this_salt),this_crypted) || + dcelogin_atmost_once) + return(False); + + if (sec_login_setup_identity( + (unsigned char *)this_user, + sec_login_no_flags, + &my_dce_sec_context, + &err) == 0) + { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE Setup Identity for %s failed: %s\n", + this_user,dce_errstr)); + return(False); + } + + my_dce_password.version_number = sec_passwd_c_version_none; + my_dce_password.pepper = NULL; + my_dce_password.key.key_type = sec_passwd_plain; + my_dce_password.key.tagged_union.plain = (idl_char *)password; + + if (sec_login_valid_and_cert_ident(my_dce_sec_context, + &my_dce_password, + &password_reset, + &auth_src, + &err) == 0 ) + { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n", + this_user,dce_errstr)); + + return(False); + } + + sec_login_set_context(my_dce_sec_context, &err); + if (err != error_status_ok ) + { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE login failed for principal %s, cant set context: %s\n", + this_user,dce_errstr)); + sec_login_purge_context(my_dce_sec_context, &err); + return(False); + } + else + { + DEBUG(0,("DCE login succeeded for principal %s on pid %d\n", + this_user, getpid())); + } + + dcelogin_atmost_once = 1; + return (True); +} + +void dfs_unlogin(void) +{ + error_status_t err; + int err2; + unsigned char dce_errstr[dce_c_error_string_len]; + + sec_login_purge_context(my_dce_sec_context, &err); + if (err != error_status_ok ) + { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE purge login context failed for server instance %d: %s\n", + getpid(), dce_errstr)); + } +} + +#endif + + +#ifdef LINUX_BIGCRYPT +/**************************************************************************** +an enhanced crypt for Linux to handle password longer than 8 characters +****************************************************************************/ +static int linux_bigcrypt(char *password,char *salt1, char *crypted) +{ +#define LINUX_PASSWORD_SEG_CHARS 8 + char salt[3]; + int i; + + StrnCpy(salt,salt1,2); + crypted +=2; + + for ( i=strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) { + char * p = crypt(password,salt) + 2; + if(strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0) + return(0); + password += LINUX_PASSWORD_SEG_CHARS; + crypted += strlen(p); + } + + return(1); +} +#endif + + +/**************************************************************************** +apply a function to upper/lower case combinations +of a string and return true if one of them returns true. +try all combinations with N uppercase letters. +offset is the first char to try and change (start with 0) +it assumes the string starts lowercased +****************************************************************************/ +static BOOL string_combinations2(char *s,int offset,BOOL (*fn)(),int N) +{ + int len = strlen(s); + int i; + +#ifdef PASSWORD_LENGTH + len = MIN(len,PASSWORD_LENGTH); +#endif + + if (N <= 0 || offset >= len) + return(fn(s)); + + for (i=offset;i<(len-(N-1));i++) + { + char c = s[i]; + if (!islower(c)) continue; + s[i] = toupper(c); + if (string_combinations2(s,i+1,fn,N-1)) + return(True); + s[i] = c; + } + return(False); +} + +/**************************************************************************** +apply a function to upper/lower case combinations +of a string and return true if one of them returns true. +try all combinations with up to N uppercase letters. +offset is the first char to try and change (start with 0) +it assumes the string starts lowercased +****************************************************************************/ +static BOOL string_combinations(char *s,BOOL (*fn)(),int N) +{ + int n; + for (n=1;n<=N;n++) + if (string_combinations2(s,0,fn,n)) return(True); + return(False); +} + + + +/**************************************************************************** +core of password checking routine +****************************************************************************/ +BOOL password_check(char *password) +{ +#ifdef AFS_AUTH + if (afs_auth(this_user,password)) return(True); +#endif + +#ifdef DFS_AUTH + if (dfs_auth(this_user,password)) return(True); +#endif + +#ifdef PWDAUTH + if (pwdauth(this_user,password) == 0) + return(True); +#endif + +#ifdef OSF1_ENH_SEC + return(strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); +#endif + +#ifdef ULTRIX_AUTH + return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0); +#endif + +#ifdef LINUX_BIGCRYPT + return(linux_bigcrypt(password,this_salt,this_crypted)); +#endif + +#ifdef NO_CRYPT + DEBUG(1,("Warning - no crypt available\n")); + return(False); +#else + return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0); +#endif +} + +#ifdef SMB_PASSWD +/**************************************************************************** +core of smb password checking routine. +****************************************************************************/ +BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8) +{ + /* Finish the encryption of part_passwd. */ + unsigned char p21[21]; + unsigned char p24[24]; + + if(part_passwd == NULL) + DEBUG(10,("No password set - allowing access\n")); + /* No password set - always true ! */ + if(part_passwd == NULL) + return 1; + + memset(p21,'\0',21); + memcpy(p21,part_passwd,16); + E_P24(p21, c8, p24); +#if DEBUG_PASSWORD + { + int i; + DEBUG(100,("Part password (P16) was |")); + for(i = 0; i < 16; i++) + DEBUG(100,("%X ", (unsigned char)part_passwd[i])); + DEBUG(100,("|\n")); + DEBUG(100,("Password from client was |")); + for(i = 0; i < 24; i++) + DEBUG(100,("%X ", (unsigned char)password[i])); + DEBUG(100,("|\n")); + DEBUG(100,("Given challenge was |")); + for(i = 0; i < 8; i++) + DEBUG(100,("%X ", (unsigned char)c8[i])); + DEBUG(100,("|\n")); + DEBUG(100,("Value from encryption was |")); + for(i = 0; i < 24; i++) + DEBUG(100,("%X ", (unsigned char)p24[i])); + DEBUG(100,("|\n")); + } +#endif + return (memcmp(p24, password, 24) == 0); +} +#endif + +/**************************************************************************** +check if a username/password is OK +****************************************************************************/ +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL is_nt_password) +{ + pstring pass2; + int level = lp_passwordlevel(); + struct passwd *pass; +#ifdef SMB_PASSWD + char challenge[8]; + struct smb_passwd *smb_pass; + BOOL challenge_done = False; +#endif + + if (password) password[pwlen] = 0; + +#ifdef SMB_PASSWD + if (pwlen == 24) + challenge_done = last_challenge(challenge); +#endif + +#if DEBUG_PASSWORD +#ifdef SMB_PASSWD + if (challenge_done) + { + int i; + DEBUG(100,("checking user=[%s] pass=[",user)); + for( i = 0; i < 24; i++) + DEBUG(100,("%0x ", (unsigned char)password[i])); + DEBUG(100,("]\n")); + } + else +#endif + DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password)); +#endif + + if (!password) + return(False); + + if (((!*password) || (!pwlen)) && !lp_null_passwords()) + return(False); + + if (pwd && !user) + { + pass = (struct passwd *) pwd; + user = pass->pw_name; + } + else + pass = Get_Pwnam(user,True); + +#ifdef SMB_PASSWD + + DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done)); + + if((pwlen == 24) && challenge_done) + { + DEBUG(4,("Checking SMB password for user %s (l=24)\n",user)); + + if (!pass) + { + DEBUG(3,("Couldn't find user %s\n",user)); + return(False); + } + + smb_pass = get_smbpwnam(user); + if(!smb_pass) + { + DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); + return(False); + } + + /* Ensure the uid's match */ + if(smb_pass->smb_userid != pass->pw_uid) + { + DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); + return(False); + } + + if(Protocol >= PROTOCOL_NT1 && is_nt_password) + { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + if(smb_pass->smb_nt_passwd != NULL) + { + DEBUG(4,("Checking NT MD4 password\n")); + if(smb_password_check(password, smb_pass->smb_nt_passwd, challenge)) + { + update_protected_database(user,True); + return(True); + } + DEBUG(4,("NT MD4 password check failed\n")); + return (False); + } + } + + /* Try against the lanman password */ + + if(smb_password_check(password, smb_pass->smb_passwd, challenge)) + { + update_protected_database(user,True); + return(True); + } + + DEBUG(3,("Error smb_password_check failed\n")); + } +#endif + + DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen)); + + if (!pass) + { + DEBUG(3,("Couldn't find user %s\n",user)); + return(False); + } + +#ifdef SHADOW_PWD + { + struct spwd *spass; + + /* many shadow systems require you to be root to get the password, + in most cases this should already be the case when this + function is called, except perhaps for IPC password changing + requests */ + + spass = getspnam(pass->pw_name); + if (spass && spass->sp_pwdp) + pass->pw_passwd = spass->sp_pwdp; + } +#endif + +#ifdef SecureWare + { + struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); + if (pr_pw && pr_pw->ufld.fd_encrypt) + pass->pw_passwd = pr_pw->ufld.fd_encrypt; + } +#endif + +#ifdef HPUX_10_TRUSTED + { + struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); + if (pr_pw && pr_pw->ufld.fd_encrypt) + pass->pw_passwd = pr_pw->ufld.fd_encrypt; + } +#endif + +#ifdef OSF1_ENH_SEC + { + struct pr_passwd *mypasswd; + DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",user)); + mypasswd = getprpwnam (user); + if ( mypasswd ) + { + strcpy(pass->pw_name,mypasswd->ufld.fd_name); + strcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt); + } + else + { + DEBUG(5,("No entry for user %s in protected database !\n",user)); + return(False); + } + } +#endif + +#ifdef ULTRIX_AUTH + { + AUTHORIZATION *ap = getauthuid( pass->pw_uid ); + if (ap) + { + strcpy( pass->pw_passwd, ap->a_password ); + endauthent(); + } + } +#endif + + /* extract relevant info */ + strcpy(this_user,pass->pw_name); + strcpy(this_salt,pass->pw_passwd); + strcpy(this_crypted,pass->pw_passwd); + + if (!*this_crypted) { + if (!lp_null_passwords()) { + DEBUG(2,("Disallowing access to %s due to null password\n",this_user)); + return(False); + } +#ifndef PWDAUTH + if (!*password) { + DEBUG(3,("Allowing access to %s with null password\n",this_user)); + return(True); + } +#endif + } + + /* try it as it came to us */ + if (password_check(password)) + { + update_protected_database(user,True); + return(True); + } + + /* if the password was given to us with mixed case then we don't + need to proceed as we know it hasn't been case modified by the + client */ + if (strhasupper(password) && strhaslower(password)) + return(False); + + /* make a copy of it */ + StrnCpy(pass2,password,sizeof(pstring)-1); + + /* try all lowercase */ + strlower(password); + if (password_check(password)) + { + update_protected_database(user,True); + return(True); + } + + /* give up? */ + if(level < 1) + { + update_protected_database(user,False); + + /* restore it */ + strcpy(password,pass2); + + return(False); + } + + /* last chance - all combinations of up to level chars upper! */ + strlower(password); + + if (string_combinations(password,password_check,level)) + { + update_protected_database(user,True); + return(True); + } + + update_protected_database(user,False); + + /* restore it */ + strcpy(password,pass2); + + return(False); +} + + + +/**************************************************************************** +check if a username is valid +****************************************************************************/ +BOOL user_ok(char *user,int snum) +{ + pstring valid, invalid; + BOOL ret; + + StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)); + StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)); + + string_sub(valid,"%S",lp_servicename(snum)); + string_sub(invalid,"%S",lp_servicename(snum)); + + ret = !user_in_list(user,invalid); + + if (ret && valid && *valid) + ret = user_in_list(user,valid); + + if (ret && lp_onlyuser(snum)) { + char *user_list = lp_username(snum); + string_sub(user_list,"%S",lp_servicename(snum)); + ret = user_in_list(user,user_list); + } + + return(ret); +} + + + + +/**************************************************************************** +validate a group username entry. Return the username or NULL +****************************************************************************/ +static char *validate_group(char *group,char *password,int pwlen,int snum) +{ +#ifdef NETGROUP + { + char *host, *user, *domain; + setnetgrent(group); + while (getnetgrent(&host, &user, &domain)) { + if (user) { + if (user_ok(user, snum) && + password_ok(user,password,pwlen,NULL,False)) { + endnetgrent(); + return(user); + } + } + } + endnetgrent(); + } +#endif + +#if HAVE_GETGRNAM + { + struct group *gptr = (struct group *)getgrnam(group); + char **member; + if (gptr) + { + member = gptr->gr_mem; + while (member && *member) + { + static fstring name; + strcpy(name,*member); + if (user_ok(name,snum) && + password_ok(name,password,pwlen,NULL,False)) + return(&name[0]); + member++; + } +#ifdef GROUP_CHECK_PWENT + { + struct passwd *pwd; + static fstring tm; + + setpwent (); + while (pwd = getpwent ()) { + if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) { + /* This Entry have PASSWORD and same GID then check pwd */ + if (password_ok(NULL, password, pwlen, pwd,False)) { + strcpy(tm, pwd->pw_name); + endpwent (); + return tm; + } + } + } + endpwent (); + } +#endif /* GROUP_CHECK_PWENT */ + } + } +#endif + return(NULL); +} + + + +/**************************************************************************** +check for authority to login to a service with a given username/password +****************************************************************************/ +BOOL authorise_login(int snum,char *user,char *password, int pwlen, + BOOL *guest,BOOL *force,int vuid) +{ + BOOL ok = False; + + *guest = False; + +#if DEBUG_PASSWORD + DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password)); +#endif + + /* there are several possabilities: + 1) login as the given user with given password + 2) login as a previously registered username with the given password + 3) login as a session list username with the given password + 4) login as a previously validated user/password pair + 5) login as the "user =" user with given password + 6) login as the "user =" user with no password (guest connection) + 7) login as guest user with no password + + if the service is guest_only then steps 1 to 5 are skipped + */ + + if (GUEST_ONLY(snum)) *force = True; + + if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) + { + + /* check the given username and password */ + if (!ok && (*user) && user_ok(user,snum)) { + ok = password_ok(user,password, pwlen, NULL, False); + if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); + } + + /* check for a previously registered guest username */ + if (!ok && (vuid >= 0) && validated_users[vuid].guest) { + if (user_ok(validated_users[vuid].name,snum) && + password_ok(validated_users[vuid].name, password, pwlen, NULL, False)) { + strcpy(user, validated_users[vuid].name); + validated_users[vuid].guest = False; + DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); + ok = True; + } + } + + + /* now check the list of session users */ + if (!ok) + { + char *auser; + char *user_list = strdup(session_users); + if (!user_list) return(False); + + for (auser=strtok(user_list,LIST_SEP); + !ok && auser; + auser = strtok(NULL,LIST_SEP)) + { + fstring user2; + strcpy(user2,auser); + if (!user_ok(user2,snum)) continue; + + if (password_ok(user2,password, pwlen, NULL, False)) { + ok = True; + strcpy(user,user2); + DEBUG(3,("ACCEPTED: session list username and given password ok\n")); + } + } + free(user_list); + } + + /* check for a previously validated username/password pair */ + if (!ok && !lp_revalidate(snum) && + (vuid >= 0) && !validated_users[vuid].guest && + user_ok(validated_users[vuid].name,snum)) { + strcpy(user,validated_users[vuid].name); + *guest = False; + DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); + ok = True; + } + + /* check for a rhosts entry */ + if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { + ok = True; + DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n")); + } + + /* check the user= fields and the given password */ + if (!ok && lp_username(snum)) { + char *auser; + pstring user_list; + StrnCpy(user_list,lp_username(snum),sizeof(pstring)); + + string_sub(user_list,"%S",lp_servicename(snum)); + + for (auser=strtok(user_list,LIST_SEP); + auser && !ok; + auser = strtok(NULL,LIST_SEP)) + { + if (*auser == '@') + { + auser = validate_group(auser+1,password,pwlen,snum); + if (auser) + { + ok = True; + strcpy(user,auser); + DEBUG(3,("ACCEPTED: group username and given password ok\n")); + } + } + else + { + fstring user2; + strcpy(user2,auser); + if (user_ok(user2,snum) && + password_ok(user2,password,pwlen,NULL, False)) + { + ok = True; + strcpy(user,user2); + DEBUG(3,("ACCEPTED: user list username and given password ok\n")); + } + } + } + } + } /* not guest only */ + + /* check for a normal guest connection */ + if (!ok && GUEST_OK(snum)) + { + fstring guestname; + StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); + if (Get_Pwnam(guestname,True)) + { + strcpy(user,guestname); + ok = True; + DEBUG(3,("ACCEPTED: guest account and guest ok\n")); + } + else + DEBUG(0,("Invalid guest account %s??\n",guestname)); + *guest = True; + *force = True; + } + + if (ok && !user_ok(user,snum)) + { + DEBUG(0,("rejected invalid user %s\n",user)); + ok = False; + } + + return(ok); +} + + +/**************************************************************************** +read the a hosts.equiv or .rhosts file and check if it +allows this user from this machine +****************************************************************************/ +static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) +{ + pstring buf; + int plus_allowed = 1; + char *file_host; + char *file_user; + FILE *fp = fopen(equiv_file, "r"); + DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); + if (! fp) return False; + while(fgets(buf, sizeof(buf), fp)) + { + trim_string(buf," "," "); + + if (buf[0] != '#' && buf[0] != '\n') + { + BOOL is_group = False; + int plus = 1; + char *bp = buf; + if (strcmp(buf, "NO_PLUS\n") == 0) + { + DEBUG(6, ("check_user_equiv NO_PLUS\n")); + plus_allowed = 0; + } + else { + if (buf[0] == '+') + { + bp++; + if (*bp == '\n' && plus_allowed) + { + /* a bare plus means everbody allowed */ + DEBUG(6, ("check_user_equiv everybody allowed\n")); + fclose(fp); + return True; + } + } + else if (buf[0] == '-') + { + bp++; + plus = 0; + } + if (*bp == '@') + { + is_group = True; + bp++; + } + file_host = strtok(bp, " \t\n"); + file_user = strtok(NULL, " \t\n"); + DEBUG(7, ("check_user_equiv %s %s\n", file_host, file_user)); + if (file_host && *file_host) + { + BOOL host_ok = False; + +#ifdef NETGROUP + /* THIS IS UNTESTED!! */ + if (is_group) + { + static char *mydomain = NULL; + if (!mydomain) + yp_get_default_domain(&mydomain); + if (mydomain && innetgr(remote,file_host,user,mydomain)) + host_ok = True; + } +#else + if (is_group) + { + DEBUG(1,("Netgroups not configured - add -DNETGROUP and recompile\n")); + continue; + } +#endif + + /* is it this host */ + /* the fact that remote has come from a call of gethostbyaddr + * means that it may have the fully qualified domain name + * so we could look up the file version to get it into + * a canonical form, but I would rather just type it + * in full in the equiv file + */ + if (!host_ok && !is_group && strequal(remote, file_host)) + host_ok = True; + + if (!host_ok) + continue; + + /* is it this user */ + if (file_user == 0 || strequal(user, file_user)) + { + fclose(fp); + DEBUG(5, ("check_user_equiv matched %s%s %s\n", + (plus ? "+" : "-"), file_host, + (file_user ? file_user : ""))); + return (plus ? True : False); + } + } + } + } + } + fclose(fp); + return False; +} + + +/**************************************************************************** +check for a possible hosts equiv or rhosts entry for the user +****************************************************************************/ +BOOL check_hosts_equiv(char *user) +{ + char *fname = NULL; + pstring rhostsfile; + struct passwd *pass = Get_Pwnam(user,True); + + extern struct from_host Client_info; + extern int Client; + + if (!pass) + return(False); + + fromhost(Client,&Client_info); + + fname = lp_hosts_equiv(); + + /* note: don't allow hosts.equiv on root */ + if (fname && *fname && (pass->pw_uid != 0)) + { + if (check_user_equiv(user,Client_info.name,fname)) + return(True); + } + + if (lp_use_rhosts()) + { + char *home = get_home_dir(user); + if (home) + { + sprintf(rhostsfile, "%s/.rhosts", home); + if (check_user_equiv(user,Client_info.name,rhostsfile)) + return(True); + } + } + + return(False); +} + + +static int password_client = -1; +static fstring pserver; + +/**************************************************************************** +attempted support for server level security +****************************************************************************/ +BOOL server_cryptkey(char *buf) +{ + pstring inbuf,outbuf; + fstring pass_protocol; + extern fstring remote_machine; + char *p; + int len; + fstring desthost; + struct in_addr dest_ip; + extern struct in_addr myip; + int port = 139; + BOOL ret; + + if (password_client >= 0) + close(password_client); + password_client = -1; + + if (Protocol < PROTOCOL_NT1) { + strcpy(pass_protocol,"LM1.2X002"); + } else { + strcpy(pass_protocol,"NT LM 0.12"); + } + + bzero(inbuf,sizeof(inbuf)); + bzero(outbuf,sizeof(outbuf)); + + for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { + strcpy(desthost,p); + standard_sub_basic(desthost); + strupper(desthost); + + dest_ip = *interpret_addr2(desthost); + if (zero_ip(dest_ip)) { + DEBUG(1,("Can't resolve address for %s\n",p)); + continue; + } + + if (memcmp(&dest_ip,&myip,sizeof(dest_ip)) == 0) { + DEBUG(1,("Password server loop - disabling password server %s\n",p)); + continue; + } + + password_client = open_socket_out(SOCK_STREAM, &dest_ip, port); + if (password_client >= 0) { + DEBUG(3,("connected to password server %s\n",p)); + StrnCpy(pserver,p,sizeof(pserver)-1); + break; + } + } + + if (password_client < 0) { + DEBUG(1,("password server not available\n")); + return(False); + } + + + /* send a session request (RFC 8002) */ + + /* put in the destination name */ + len = 4; + p = outbuf+len; + name_mangle(desthost,p,' '); + len += name_len(p); + + /* and my name */ + p = outbuf+len; + name_mangle(remote_machine,p,' '); + len += name_len(p); + + _smb_setlen(outbuf,len); + CVAL(outbuf,0) = 0x81; + + send_smb(password_client,outbuf); + receive_smb(password_client,inbuf,5000); + + if (CVAL(inbuf,0) != 0x82) { + DEBUG(1,("%s rejected the session\n",pserver)); + close(password_client); password_client = -1; + return(False); + } + + DEBUG(3,("got session\n")); + + bzero(outbuf,smb_size); + + /* setup the protocol string */ + set_message(outbuf,0,strlen(pass_protocol)+2,True); + p = smb_buf(outbuf); + *p++ = 2; + strcpy(p,pass_protocol); + + CVAL(outbuf,smb_com) = SMBnegprot; + CVAL(outbuf,smb_flg) = 0x8; + SSVAL(outbuf,smb_flg2,0x1); + + send_smb(password_client,outbuf); + ret = receive_smb(password_client,inbuf,5000); + + if (!ret || CVAL(inbuf,smb_rcls) || SVAL(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)) { + 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); + + DEBUG(3,("password server OK\n")); + + return(True); +} + +/**************************************************************************** +attempted support for server level security +****************************************************************************/ +BOOL server_validate(char *buf) +{ + pstring inbuf,outbuf; + BOOL ret; + + if (password_client < 0) { + DEBUG(1,("%s not connected\n",pserver)); + return(False); + } + + bzero(inbuf,sizeof(inbuf)); + memcpy(outbuf,buf,sizeof(outbuf)); + + /* send a session setup command */ + CVAL(outbuf,smb_flg) = 0x8; + SSVAL(outbuf,smb_flg2,0x1); + CVAL(outbuf,smb_vwv0) = 0xFF; + + set_message(outbuf,smb_numwords(outbuf),smb_buflen(outbuf),False); + + SCVAL(inbuf,smb_rcls,1); + + send_smb(password_client,outbuf); + ret = receive_smb(password_client,inbuf,5000); + + if (!ret || CVAL(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) { + DEBUG(1,("password server %s gave us guest only\n",pserver)); + return(False); + } + + DEBUG(3,("password server %s accepted the password\n",pserver)); + +#ifndef KEEP_PASSWORD_SERVER_OPEN + close(password_client); password_client= -1; +#endif + + return(True); +} + + -- cgit From 03aeb8af5d97c1be6122ea90d53fa386e22c3046 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 4 May 1996 10:45:50 +0000 Subject: fix a netgroup bug (innetgr() was being called with the args in the wrong order!) (This used to be commit 4419093d336bad30b194b959231fed04cbc8a1cf) --- source3/smbd/password.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 87c1fef94c..863032df87 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1153,13 +1153,12 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) BOOL host_ok = False; #ifdef NETGROUP - /* THIS IS UNTESTED!! */ if (is_group) { static char *mydomain = NULL; if (!mydomain) yp_get_default_domain(&mydomain); - if (mydomain && innetgr(remote,file_host,user,mydomain)) + if (mydomain && innetgr(file_host,remote,user,mydomain)) host_ok = True; } #else -- cgit From 11f7553c7495ecae3e918d8329107174c2ce0149 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 5 May 1996 11:25:07 +0000 Subject: turn on KEEP_PASSWORD_SERVER_OPEN by default (This used to be commit d2676cdd0b44fc4fc825118e510bac2c3f1e40d9) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 863032df87..fcfe1b4a2c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1241,7 +1241,7 @@ BOOL check_hosts_equiv(char *user) } -static int password_client = -1; +int password_client = -1; static fstring pserver; /**************************************************************************** @@ -1405,7 +1405,7 @@ BOOL server_validate(char *buf) DEBUG(3,("password server %s accepted the password\n",pserver)); -#ifndef KEEP_PASSWORD_SERVER_OPEN +#if !KEEP_PASSWORD_SERVER_OPEN close(password_client); password_client= -1; #endif -- cgit From 1956d1349441d8d5694df6dda67528bec4b1c10e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 May 1996 07:47:47 +0000 Subject: cleanups to make thinsg compile cleanly (This used to be commit 39fbeb04ae938594c380d97ebe67c012fa0dd51a) --- source3/smbd/password.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fcfe1b4a2c..6031daf5f1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -52,7 +52,7 @@ void generate_next_challenge(char *challenge) v2 = (counter++) * getpid() + tval.tv_usec; SIVAL(challenge,0,v1); SIVAL(challenge,4,v2); - E1(challenge,"SAMBA",saved_challenge); + E1(challenge,"SAMBA",(char *)saved_challenge); memcpy(challenge,saved_challenge,8); challenge_sent = True; } @@ -684,7 +684,9 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL if(smb_pass->smb_nt_passwd != NULL) { DEBUG(4,("Checking NT MD4 password\n")); - if(smb_password_check(password, smb_pass->smb_nt_passwd, challenge)) + if(smb_password_check(password, + smb_pass->smb_nt_passwd, + (char *)challenge)) { update_protected_database(user,True); return(True); @@ -696,11 +698,12 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL /* Try against the lanman password */ - if(smb_password_check(password, smb_pass->smb_passwd, challenge)) - { - update_protected_database(user,True); - return(True); - } + if (smb_password_check(password, + smb_pass->smb_passwd, + (char *)challenge)) { + update_protected_database(user,True); + return(True); + } DEBUG(3,("Error smb_password_check failed\n")); } -- cgit From 58734631b4233ec08b7a262587e400792f31f185 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 31 May 1996 15:13:29 +0000 Subject: Lots of changes! - add faq info on NT printer handling - add "delete readonly" option to help rcs users - add stuff to man pages on new printer options - add "proxy name resolution" option - add "command string" -c option to smbclient (thanks Ken) - split time functions into time.c - rearrange the quotas stuff a bit and fix some bugs - complete rehash of the time handling code thanks to Paul Eggert - fix nmblookup output a bit - add plp print queue parsing from Bertrand Wallrich (This used to be commit 635b56f19c817527c52e9bbde31faa6a8a47777b) --- source3/smbd/password.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6031daf5f1..b8111fc739 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -287,15 +287,13 @@ static void update_protected_database( char *user, BOOL result) #ifdef OSF1_ENH_SEC struct pr_passwd *mypasswd; time_t starttime; - long tz; mypasswd = getprpwnam (user); starttime = time (NULL); - tz = mktime ( localtime ( &starttime ) ); if (result) { - mypasswd->ufld.fd_slogin = tz; + mypasswd->ufld.fd_slogin = starttime; mypasswd->ufld.fd_nlogins = 0; putprpwnam(user,mypasswd); @@ -304,7 +302,7 @@ static void update_protected_database( char *user, BOOL result) } else { - mypasswd->ufld.fd_ulogin = tz; + mypasswd->ufld.fd_ulogin = starttime; mypasswd->ufld.fd_nlogins = mypasswd->ufld.fd_nlogins + 1; if ( mypasswd->ufld.fd_max_tries != 0 && mypasswd->ufld.fd_nlogins > mypasswd->ufld.fd_max_tries ) { -- cgit From a2c1623827406667a4f2f058c24f1d971f6627f8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 4 Jun 1996 06:42:03 +0000 Subject: a huge pile of changes :-) The biggest thing is the integration of Lukes new nmbd. Its still largely untested, so we will really need some feedback I've also added auto prototype generation and cleaned up a lot of minor things as a result (This used to be commit 0d8dcfa13c527ec2c8aca39ba49c09e4e694b26c) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b8111fc739..31d9191271 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1258,7 +1258,7 @@ BOOL server_cryptkey(char *buf) fstring desthost; struct in_addr dest_ip; extern struct in_addr myip; - int port = 139; + int port = SMB_PORT; BOOL ret; if (password_client >= 0) -- cgit From b9ae225b28f4707609e6436dad4be7ebdd7e181f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 6 Jun 1996 11:43:09 +0000 Subject: - added interface.c and removed all the references to myip, bcast_ip and Netmask, instead replacing them with calls to routines in interface.c - got rid of old MAXINT define - added code to ensure we only return one entry for each name in the ipc enum routines - added new_only option to add_netbios_entry() to prevent overwriting of important names - minor time handling fixup (This used to be commit 7ed71b73ae745da099072eee36fc2700d1d91407) --- source3/smbd/password.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 31d9191271..c2fe8a4f0d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -43,7 +43,6 @@ Get the next challenge value - no repeats. ********************************************************************/ void generate_next_challenge(char *challenge) { - extern void E1(char *,char *,char *); static int counter = 0; struct timeval tval; int v1,v2; @@ -1257,7 +1256,6 @@ BOOL server_cryptkey(char *buf) int len; fstring desthost; struct in_addr dest_ip; - extern struct in_addr myip; int port = SMB_PORT; BOOL ret; @@ -1285,7 +1283,7 @@ BOOL server_cryptkey(char *buf) continue; } - if (memcmp(&dest_ip,&myip,sizeof(dest_ip)) == 0) { + if (ismyip(dest_ip)) { DEBUG(1,("Password server loop - disabling password server %s\n",p)); continue; } -- cgit From 7e3b4a1c0df1434eb3d02f93c736ce065f9898d8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 04:38:24 +0000 Subject: got rid of a lot of redundent header files as we now globally generate prototypes automatically using "make proto". This is much less prone to error than the old method of manually adding prototypes (This used to be commit b551dc98f7cc194a5fc2e67a4ebae7fd67a01bbc) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c2fe8a4f0d..ae548b8266 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -20,7 +20,6 @@ */ #include "includes.h" -#include "loadparm.h" extern int DEBUGLEVEL; extern int Protocol; -- cgit From a521fe8a274c8a043cf77641dd4160fdef803533 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Jun 1996 05:16:19 +0000 Subject: a cleanup of the receive_smb() usage, adding timeouts in some places also added paranoid code in the main process() loop of smbd to detect when smbd is looping uselessly. This should stop the "smbd is chewing lots of cpu" reports (This used to be commit 8e9dce34d50d673cb50531f0c4c7672ce2522cef) --- source3/smbd/password.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ae548b8266..a5f597682f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1318,9 +1318,10 @@ BOOL server_cryptkey(char *buf) CVAL(outbuf,0) = 0x81; send_smb(password_client,outbuf); - receive_smb(password_client,inbuf,5000); + - if (CVAL(inbuf,0) != 0x82) { + if (!receive_smb(password_client,inbuf,5000) || + CVAL(inbuf,0) != 0x82) { DEBUG(1,("%s rejected the session\n",pserver)); close(password_client); password_client = -1; return(False); -- cgit From 9155889092ac9ff476d950a0c1b624ebad3cdad6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 22 Aug 1996 06:32:03 +0000 Subject: - add timeouts to connect() for password server connections. This makes multiple password servers practical. (This used to be commit 5c3e8326cc45d3cbd076475e445ce461a2bf7560) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a5f597682f..fd3ff4fd17 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1287,7 +1287,7 @@ BOOL server_cryptkey(char *buf) continue; } - password_client = open_socket_out(SOCK_STREAM, &dest_ip, port); + password_client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT); if (password_client >= 0) { DEBUG(3,("connected to password server %s\n",p)); StrnCpy(pserver,p,sizeof(pserver)-1); -- cgit From 11d9539d755d5c5accb4481577781b8b7bfeda50 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 2 Oct 1996 14:06:17 +0000 Subject: - accept either NT or lanman passwords in tconX (This used to be commit b6c1c60d72e1625ca172b8f8eb07078413611468) --- source3/smbd/password.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fd3ff4fd17..41dfd838ed 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -597,7 +597,7 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha /**************************************************************************** check if a username/password is OK ****************************************************************************/ -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL is_nt_password) +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) { pstring pass2; int level = lp_passwordlevel(); @@ -672,7 +672,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL return(False); } - if(Protocol >= PROTOCOL_NT1 && is_nt_password) + if(Protocol >= PROTOCOL_NT1) { /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). @@ -688,7 +688,6 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd, BOOL return(True); } DEBUG(4,("NT MD4 password check failed\n")); - return (False); } } @@ -888,7 +887,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && - password_ok(user,password,pwlen,NULL,False)) { + password_ok(user,password,pwlen,NULL)) { endnetgrent(); return(user); } @@ -910,7 +909,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) static fstring name; strcpy(name,*member); if (user_ok(name,snum) && - password_ok(name,password,pwlen,NULL,False)) + password_ok(name,password,pwlen,NULL)) return(&name[0]); member++; } @@ -923,7 +922,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (pwd = getpwent ()) { if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) { /* This Entry have PASSWORD and same GID then check pwd */ - if (password_ok(NULL, password, pwlen, pwd,False)) { + if (password_ok(NULL, password, pwlen, pwd)) { strcpy(tm, pwd->pw_name); endpwent (); return tm; @@ -974,14 +973,14 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL, False); + ok = password_ok(user,password, pwlen, NULL); if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); } /* check for a previously registered guest username */ if (!ok && (vuid >= 0) && validated_users[vuid].guest) { if (user_ok(validated_users[vuid].name,snum) && - password_ok(validated_users[vuid].name, password, pwlen, NULL, False)) { + password_ok(validated_users[vuid].name, password, pwlen, NULL)) { strcpy(user, validated_users[vuid].name); validated_users[vuid].guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); @@ -1005,7 +1004,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, strcpy(user2,auser); if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen, NULL, False)) { + if (password_ok(user2,password, pwlen, NULL)) { ok = True; strcpy(user,user2); DEBUG(3,("ACCEPTED: session list username and given password ok\n")); @@ -1057,7 +1056,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstring user2; strcpy(user2,auser); if (user_ok(user2,snum) && - password_ok(user2,password,pwlen,NULL, False)) + password_ok(user2,password,pwlen,NULL)) { ok = True; strcpy(user,user2); -- cgit From e5893bdfbef0ac16772199d7ec6fac7d3e4f8431 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Oct 1996 10:41:13 +0000 Subject: I have fixed quite a few important bugs in this commit. Luke, can you take special note of the bug fixes to nmbd so you can propogate them to your new code. - rewrote the code that used to use fromhost(). We now call gethostbyaddr() only if necessary and a maximum of once per connection. Calling gethostbyaddr() causes problems on some systems so avoiding it if possible is a good thing :-) - added the "fake oplocks" option. See the docs in smb.conf(5) and Speed.txt - fixed a serious bug in nmbd where it would try a DNS lookup on FIND_SELF queries. This caused a lot of unnecessary (and incorrect) DNS lookups to happen. FIND_SELF queries should only go to the internal name tables. - don't set FIND_SELF for name queries if we are a wins proxy, as we are supposed to be answering queries for other hosts. - fixed a bug in nmbd which had "if (search | FIND_LOCAL)" instead of "if (search & FIND_LOCAL)". Luke, this was in nameservreply.c - the above 3 bugs together meant that DNS queries were being cached, but the cache wasn't being used, so every query was going to DNS, no wonder nmbd has been chewing so much CPU time! Another side effect was that queries on names in lmhosts weren't being answered for bcast queries with "wins proxy" set. - ignore the maxxmit for seconday session setups (see CIFS spec) - close user opened files in a uLogoffX for user level security (see CIFS spec) - added uid into the files struct to support the above change (This used to be commit ea472b7217b7693627a13a7b1e428a0a6a3d8755) --- source3/smbd/password.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 41dfd838ed..d17bb86be4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1207,20 +1207,15 @@ BOOL check_hosts_equiv(char *user) pstring rhostsfile; struct passwd *pass = Get_Pwnam(user,True); - extern struct from_host Client_info; - extern int Client; - if (!pass) return(False); - fromhost(Client,&Client_info); - fname = lp_hosts_equiv(); /* note: don't allow hosts.equiv on root */ if (fname && *fname && (pass->pw_uid != 0)) { - if (check_user_equiv(user,Client_info.name,fname)) + if (check_user_equiv(user,client_name(),fname)) return(True); } @@ -1230,7 +1225,7 @@ BOOL check_hosts_equiv(char *user) if (home) { sprintf(rhostsfile, "%s/.rhosts", home); - if (check_user_equiv(user,Client_info.name,rhostsfile)) + if (check_user_equiv(user,client_name(),rhostsfile)) return(True); } } -- cgit From 8c5c55fea5656df4fcc241c1f989674cf1b54f9e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Fri, 25 Oct 1996 20:18:28 +0000 Subject: Core of the changes for returning smb_uid's. smb_uid's are now returned as an index plus offset into the valudated_users table. The offset (100) is added so that an smb_uid of zero becomes an invalid value. All access into the validated_users table are done by removing the offset and indexing into the table. Out of ranges return NULL. Causes accesses into the validated_users table to be more consistant and controlled. This change made due to the fact that the uid field is only 16 bits in the smb header and we need for this not to be a unix user id (which can ge 32 bits). jra@cygnus.com (This used to be commit ac265eff85a043e139b259e400fbbc444a94c97c) --- source3/smbd/password.c | 117 +++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 60 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index d17bb86be4..4f9f91d76d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -80,32 +80,18 @@ BOOL last_challenge(char *challenge) static user_struct *validated_users = NULL; static int num_validated_users = 0; -/**************************************************************************** -check if a uid has been validated, and return an index if it has. -1 if not -****************************************************************************/ -int valid_uid(int uid) -{ - int i; - if (uid == -1) return(-1); - - for (i=0;i= (uint16)num_validated_users) || + (validated_users[vuid].uid == -1) || (validated_users[vuid].gid == -1)) return NULL; return &validated_users[vuid]; } @@ -113,56 +99,65 @@ user_struct *get_valid_user_struct(int uid) /**************************************************************************** invalidate a uid ****************************************************************************/ -void invalidate_uid(int uid) +void invalidate_vuid(uint16 vuid) { - int i; - for (i=0;iuid = -1; - vuser->gid = -1; - vuser->user_ngroups = 0; - if(vuser->user_groups && - (vuser->user_groups != (gid_t *)vuser->user_igroups)) - free(vuser->user_groups); - vuser->user_groups = NULL; - if(vuser->user_igroups) - free(vuser->user_igroups); - vuser->user_igroups = NULL; - } + user_struct *vuser = get_valid_user_struct(vuid); + if(vuser == 0) + return; + + vuser->uid = -1; + vuser->gid = -1; + vuser->user_ngroups = 0; + if(vuser->user_groups && + (vuser->user_groups != (gid_t *)vuser->user_igroups)) + free(vuser->user_groups); + vuser->user_groups = NULL; + if(vuser->user_igroups) + free(vuser->user_igroups); + vuser->user_igroups = NULL; } /**************************************************************************** return a validated username ****************************************************************************/ -char *validated_username(int vuid) +char *validated_username(uint16 vuid) { - return(validated_users[vuid].name); + user_struct *vuser = get_valid_user_struct(vuid); + if(vuser == 0) + return 0; + return(vuser->name); } /**************************************************************************** register a uid/name pair as being valid and that a valid password -has been given. +has been given. vuid is biased by an offset. This allows us to +tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -void register_uid(int uid,int gid, char *name,BOOL guest) +uint16 register_vuid(int uid,int gid, char *name,BOOL guest) { user_struct *vuser; - if (valid_uid(uid) >= 0) - return; - validated_users = (user_struct *)Realloc(validated_users, - sizeof(user_struct)* - (num_validated_users+1)); + int i; + for(i = 0; i < num_validated_users; i++) { + vuser = &validated_users[i]; + if( vuser->uid == uid ) + return i; /* User already validated */ + } + validated_users = (user_struct *)Realloc(validated_users, + sizeof(user_struct)* + (num_validated_users+1)); + if (!validated_users) { DEBUG(0,("Failed to realloc users struct!\n")); - return; + return UID_FIELD_INVALID; } vuser = &validated_users[num_validated_users]; + num_validated_users++; + vuser->uid = uid; vuser->gid = gid; vuser->guest = guest; @@ -180,8 +175,8 @@ void register_uid(int uid,int gid, char *name,BOOL guest) &vuser->user_groups); DEBUG(3,("uid %d registered to name %s\n",uid,name)); - - num_validated_users++; + + return (uint16)((num_validated_users - 1) + VUID_OFFSET); } @@ -944,7 +939,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) check for authority to login to a service with a given username/password ****************************************************************************/ BOOL authorise_login(int snum,char *user,char *password, int pwlen, - BOOL *guest,BOOL *force,int vuid) + BOOL *guest,BOOL *force,uint16 vuid) { BOOL ok = False; @@ -971,6 +966,8 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { + user_struct *vuser = get_valid_user_struct(vuid); + /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { ok = password_ok(user,password, pwlen, NULL); @@ -978,11 +975,11 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, } /* check for a previously registered guest username */ - if (!ok && (vuid >= 0) && validated_users[vuid].guest) { - if (user_ok(validated_users[vuid].name,snum) && - password_ok(validated_users[vuid].name, password, pwlen, NULL)) { - strcpy(user, validated_users[vuid].name); - validated_users[vuid].guest = False; + if (!ok && (vuser != 0) && vuser->guest) { + if (user_ok(vuser->name,snum) && + password_ok(vuser->name, password, pwlen, NULL)) { + strcpy(user, vuser->name); + vuser->guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); ok = True; } @@ -1015,9 +1012,9 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check for a previously validated username/password pair */ if (!ok && !lp_revalidate(snum) && - (vuid >= 0) && !validated_users[vuid].guest && - user_ok(validated_users[vuid].name,snum)) { - strcpy(user,validated_users[vuid].name); + (vuser != 0) && !vuser->guest && + user_ok(vuser->name,snum)) { + strcpy(user,vuser->name); *guest = False; DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); ok = True; -- cgit From 7da995a1dd352712f1b5d8ad2545408281265b0f Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Sat, 9 Nov 1996 01:56:20 +0000 Subject: Set num_validated_users to zero if Realloc fails. (This used to be commit 57121e609e927d16389793c7969f5fb944c7669d) --- source3/smbd/password.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4f9f91d76d..9b06e0dcb5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -152,6 +152,7 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) if (!validated_users) { DEBUG(0,("Failed to realloc users struct!\n")); + num_validated_users = 0; return UID_FIELD_INVALID; } -- cgit From d613892674d40962880356ac4915d7321ae2573a Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 2 Jan 1997 04:04:49 +0000 Subject: JHT ==> Added extensions for PAM (Pluggable Authentication Module) support for Linux and other little beasties that use PAM. Source: ftp.redhat.com/pub/Incoming/samba-1.9.16p9.src.rpm Originally from RedHat modifications to samba-1.9.15p8 (This used to be commit 79145bad569c71a7485b40a74e91eb93b52d6392) --- source3/smbd/password.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 102 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9b06e0dcb5..8c1a1026cc 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -312,6 +312,103 @@ static void update_protected_database( char *user, BOOL result) } +#ifdef USE_PAM +/******************************************************************* +check on PAM authentication +********************************************************************/ + +/* We first need some helper functions */ +#include +/* Static variables used to communicate between the conversation function + * and the server_login function + */ +static char *PAM_username; +static char *PAM_password; + +/* PAM conversation function + * Here we assume (for now, at least) that echo on means login name, and + * echo off means password. + */ +static int PAM_conv (int num_msg, + const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr) { + int count = 0, replies = 0; + struct pam_response *reply = NULL; + int size = sizeof(struct pam_response); + + #define GET_MEM if (reply) realloc(reply, size); else reply = malloc(size); \ + if (!reply) return PAM_CONV_ERR; \ + size += sizeof(struct pam_response) + #define COPY_STRING(s) (s) ? strdup(s) : NULL + + for (count = 0; count < num_msg; count++) { + switch (msg[count]->msg_style) { + case PAM_PROMPT_ECHO_ON: + GET_MEM; + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies++].resp = COPY_STRING(PAM_username); + /* PAM frees resp */ + break; + case PAM_PROMPT_ECHO_OFF: + GET_MEM; + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies++].resp = COPY_STRING(PAM_password); + /* PAM frees resp */ + break; + case PAM_TEXT_INFO: + /* ignore it... */ + break; + case PAM_ERROR_MSG: + default: + /* Must be an error of some sort... */ + free (reply); + return PAM_CONV_ERR; + } + } + if (reply) *resp = reply; + return PAM_SUCCESS; +} +static struct pam_conv PAM_conversation = { + &PAM_conv, + NULL +}; + + +static BOOL pam_auth(char *this_user,char *password) +{ + pam_handle_t *pamh; + int pam_error; + + /* Now use PAM to do authentication. For now, we won't worry about + * session logging, only authentication. Bail out if there are any + * errors. Since this is a limited protocol, and an even more limited + * function within a server speaking this protocol, we can't be as + * verbose as would otherwise make sense. + * Query: should we be using PAM_SILENT to shut PAM up? + */ + #define PAM_BAIL if (pam_error != PAM_SUCCESS) { \ + pam_end(pamh, 0); return False; \ + } + PAM_password = password; + PAM_username = this_user; + pam_error = pam_start("samba", this_user, &PAM_conversation, &pamh); + PAM_BAIL; + pam_error = pam_authenticate(pamh, 0); + PAM_BAIL; + /* It is not clear to me that account management is the right thing + * to do, but it is not clear that it isn't, either. This can be + * removed if no account management should be done. Alternately, + * put a pam_allow.so entry in /etc/pam.conf for account handling. */ + pam_error = pam_acct_mgmt(pamh, 0); + PAM_BAIL; + pam_end(pamh, PAM_SUCCESS); + /* If this point is reached, the user has been authenticated. */ + return(True); +} +#endif + + #ifdef AFS_AUTH /******************************************************************* check on AFS authentication @@ -513,6 +610,11 @@ core of password checking routine ****************************************************************************/ BOOL password_check(char *password) { + +#ifdef USE_PAM + if (pam_auth(this_user,password)) return(True); +#endif + #ifdef AFS_AUTH if (afs_auth(this_user,password)) return(True); #endif -- cgit From cc55a88ddc9c08cc669da731e9f7aafc379680ee Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 4 Feb 1997 10:35:38 +0000 Subject: JHT ===> Fixed potential PAM Security hole and second chance syndrome spurious warning message "Warning - no crypt available" (This used to be commit dc559428b85474ff4d80f37f421365a3910a8861) --- source3/smbd/password.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8c1a1026cc..3ccc1e4cfd 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -612,7 +612,16 @@ BOOL password_check(char *password) { #ifdef USE_PAM +/* This falls through if the password check fails + - if NO_CRYPT is defined this causes an error msg + saying Warning - no crypt available + - if NO_CRYPT is NOT defined this is a potential security hole + as it may authenticate via the crypt call when PAM + settings say it should fail. if (pam_auth(this_user,password)) return(True); +Hence we make a direct return to avoid a second chance!!! +*/ + return (pam_auth(this_user,password)); #endif #ifdef AFS_AUTH -- cgit From 121c81e3d68f1748f114a2530a9eb67f7f658fda Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 7 May 1997 17:56:46 +0000 Subject: added automount home directory support. contributed by simeon@bangor.co.uk and a mini bug-fix by rob.nacarrato@sheridanc.on.ca reads in an entry from the auto.home file for the user when they log in, and mounts their home directory as the default path for the [homes] service. i might add this as to the %substitution system, so that you can specify subdirectories for the user profiles, mainly. lkcl (This used to be commit 0bb6acc358243c49e19de9d5cc95f5124ac11b7c) --- source3/smbd/password.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3ccc1e4cfd..2c24913c86 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,6 +21,10 @@ #include "includes.h" +#if (defined(NETGROUP) && defined (AUTOMOUNT)) +#include "rpcsvc/ypclnt.h" +#endif + extern int DEBUGLEVEL; extern int Protocol; @@ -138,6 +142,17 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) { user_struct *vuser; +#if (defined(NETGROUP) && defined (AUTOMOUNT)) + int nis_error; /* returned by yp all functions */ + char *nis_result; /* yp_match inits this */ + int nis_result_len; /* and set this */ + char *nis_domain; /* yp_get_default_domain inits this */ + char *nis_map = (char *)lp_nis_home_map_name(); + int home_server_len; +#endif + struct passwd *pwfile; /* for getting real name from passwd file */ + int real_name_len; + int i; for(i = 0; i < num_validated_users; i++) { vuser = &validated_users[i]; @@ -177,6 +192,46 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) DEBUG(3,("uid %d registered to name %s\n",uid,name)); +#if (defined(NETGROUP) && defined (AUTOMOUNT)) + vuser->home_share = NULL; + DEBUG(3, ("Setting default HOMESHR to: \\\\logon server\\HOMES\n")); + vuser->home_share = Realloc(vuser->home_share, 32); + strcpy(vuser->home_share,"\\\\%L\\HOMES"); + + if (nis_error = yp_get_default_domain(&nis_domain)) + DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); + DEBUG(3, ("NIS Domain: %s\n", nis_domain)); + + if (nis_error = yp_match(nis_domain, nis_map, vuser->name, strlen(vuser->name), + &nis_result, &nis_result_len)) + DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); + if (!nis_error && lp_nis_home_map()) { + home_server_len = strcspn(nis_result,":"); + DEBUG(3, ("NIS lookup succeeded\n\tHome server length: %d\n",home_server_len)); + vuser->home_share = (char *)Realloc(vuser->home_share, home_server_len+12); + DEBUG(3, ("\tAllocated %d bytes for HOMESHR\n",home_server_len+12 )); + strcpy(vuser->home_share,"\\\\"); + strncat(vuser->home_share, nis_result, home_server_len); + strcat(vuser->home_share,"\\homes"); + DEBUG(2,("\tUser = %s\n\tUID = %d\n\tNIS result = %s\n\tHOMESHR = %s\n", + vuser->name, vuser->uid, nis_result, vuser->home_share)); + } +#endif + + vuser->real_name = NULL; + DEBUG(3, ("Clearing default real name\n")); + vuser->real_name = Realloc(vuser->real_name, 15); + strcpy(vuser->real_name, "\0"); + if (lp_unix_realname()) { + pwfile=getpwnam(vuser->name); + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); + real_name_len = strcspn(pwfile->pw_gecos, ","); + DEBUG(3, ("Real name length: %d\n", real_name_len)); + vuser->real_name = (char *)Realloc(vuser->real_name, real_name_len+1); + strncpy(vuser->real_name, pwfile->pw_gecos, real_name_len); + vuser->real_name[real_name_len]='\0'; + } + return (uint16)((num_validated_users - 1) + VUID_OFFSET); } -- cgit From 0f1f0ceb9519368188f695e18e2341ccfd1b2d15 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 8 May 1997 01:14:17 +0000 Subject: 'The mother of all checkins' :-). Jeremy Allison (jallison@whistle.com) Wed May 7 1997: Update for 1.9.17alpha1 release - 'browsefix release' designed to make browsing across subnets work. byteorder.h: Updated copyright to 1997. charcnv.c: Updated copyright to 1997. charset.c Updated copyright to 1997. charset.h Updated copyright to 1997. client.c Updated copyright to 1997. clientutil.c Updated copyright to 1997. dir.c Updated copyright to 1997. fault.c Updated copyright to 1997. includes.h Updated copyright to 1997. interface.c Updated copyright to 1997. ipc.c Updated copyright to 1997. kanji.c Updated copyright to 1997. kanji.h Updated copyright to 1997. loadparm.c Updated copyright to 1997. locking.c Updated copyright to 1997. mangle.c Updated copyright to 1997. message.c Updated copyright to 1997. nameannounce.c Made use of WINS subnet explicit. Added reset_announce_timer() so announcement can be made immediately when we become a master. Expanded code to do sync with dmb. namebrowse.c Removed redundent checks for AM_MASTER in sync code. Made use of WINS subnet explicit. namedbname.c Made use of WINS subnet explicit. namedbresp.c Made use of WINS subnet explicit. namedbserver.c Made use of WINS subnet explicit. namedbsubnet.c Explicitly add workgroup to WINS subnet when we become a dmb. Made use of WINS subnet explicit. namedbwork.c Made use of WINS subnet explicit. Removed redundent check_work_servertype() function. nameelect.c Explicitly add workgroup to WINS subnet when we become a master browser. Made use of WINS subnet explicit. namelogon.c Updated copyright to 1997. namepacket.c Updated copyright to 1997. namequery.c Updated copyright to 1997. nameresp.c Made use of WINS subnet explicit. Made nmbd fail if configured as master browser and one exists already. nameserv.c Made use of WINS subnet explicit. Remove redundent logon server and domain master code. nameserv.h Add emumerate subnet macros. nameservreply.c Made use of WINS subnet explicit. nameservresp.c Updated copyright to 1997. namework.c Made use of WINS subnet explicit. Updated code to add sync browser entries to add subnet parameter. nmbd.c Added sanity check for misconfigured nmbd. nmblib.c Updated copyright to 1997. nmblookup.c Updated copyright to 1997. nmbsync.c Removed redundent AM_ANY_MASTER check. params.c Updated copyright to 1997. password.c Updated copyright to 1997. pipes.c Updated copyright to 1997. predict.c Updated copyright to 1997. printing.c Updated copyright to 1997. proto.h Changed protos for new nmbd code. quotas.c Updated copyright to 1997. replace.c Updated copyright to 1997. reply.c Updated copyright to 1997. server.c Updated copyright to 1997. shmem.c Updated copyright to 1997. smb.h Updated copyright to 1997. smbencrypt.c Updated copyright to 1997. smbpasswd.c Updated copyright to 1997. smbrun.c Updated copyright to 1997. status.c Updated copyright to 1997. system.c Updated copyright to 1997. testparm.c Updated copyright to 1997. testprns.c Updated copyright to 1997. time.c Updated copyright to 1997. trans2.c Updated copyright to 1997. trans2.h Updated copyright to 1997. uid.c Updated copyright to 1997. username.c Updated copyright to 1997. util.c Updated copyright to 1997. version.h Changed to 1.9.17alpha1. (This used to be commit cf23a155a1315f50d488794a2caf88402bf3e3e6) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2c24913c86..7885fd1bbc 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Password and authentication handling - Copyright (C) Andrew Tridgell 1992-1995 + Copyright (C) Andrew Tridgell 1992-1997 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From 16c87e9198ab645df15209370288fefbd832f81e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Wed, 18 Jun 1997 01:04:57 +0000 Subject: Fixed *really* stupid bug in register_vuid - only a problem on multi-user NT systems. Jeremy (jallison@whistle.com) (This used to be commit 6ca5c8ca3294cde56e28558bcb02c144225903d8) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 7885fd1bbc..803418c97e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -157,7 +157,7 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) for(i = 0; i < num_validated_users; i++) { vuser = &validated_users[i]; if( vuser->uid == uid ) - return i; /* User already validated */ + return (uint16)(i + VUID_OFFSET); /* User already validated */ } validated_users = (user_struct *)Realloc(validated_users, -- cgit From fc3901122d51b76b5dd5d6a798dace35760590ad Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 3 Jul 1997 17:19:46 +0000 Subject: Fixes for UnixWare 2.x with shadow passwords from Warren Young . (This used to be commit 885b42b44752249c85bb924c9ceefa5b710225da) --- source3/smbd/password.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 803418c97e..2ba09f5ad9 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -887,6 +887,15 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) if (spass && spass->sp_pwdp) pass->pw_passwd = spass->sp_pwdp; } +#elif defined(IA_UINFO) + { + /* Need to get password with SVR4.2's ia_ functions instead of + get{sp,pw}ent functions. Required by UnixWare 2.x, tested on + version 2.1. (tangent@cyberport.com) */ + uinfo_t uinfo; + if (ia_openinfo(pass->pw_name, &uinfo) != -1) + ia_get_logpwd(uinfo, &(pass->pw_passwd)); + } #endif #ifdef SecureWare -- cgit From 8b904f4ecc7b6bd6558d40fda4184112bbb10366 Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Thu, 17 Jul 1997 20:11:58 +0000 Subject: Makefile: Added krb5 option from Nathan Neulinger includes.h: Added krb5 option from Nathan Neulinger , added SGI5 fix. password.c: Added krb5 option from Nathan Neulinger quotas.c: Added inode quote fix. reply.c: removed redundent code. server.c: Changed error debug to 0, removed redundent check. util.c: Added close_low_fd() to become_daemon - fix for rsh from Johnathan Knight. Jeremy (jallison@whistle.com) (This used to be commit 256afb764828b0a6dad5529d62501bc9ea2807ee) --- source3/smbd/password.c | 87 ++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2ba09f5ad9..e00028d87e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -585,6 +585,86 @@ void dfs_unlogin(void) #endif +#ifdef KRB5_AUTH +/******************************************************************* +check on Kerberos authentication +********************************************************************/ +static BOOL krb5_auth(char *this_user,char *password) +{ + krb5_data tgtname = { + 0, + KRB5_TGS_NAME_SIZE, + KRB5_TGS_NAME + }; + krb5_context kcontext; + krb5_principal kprinc; + krb5_principal server; + krb5_creds kcreds; + int options = 0; + krb5_address **addrs = (krb5_address **)0; + krb5_preauthtype *preauth = NULL; + krb5_keytab keytab = NULL; + krb5_timestamp now; + krb5_ccache ccache = NULL; + int retval; + char *name; + + if ( retval=krb5_init_context(&kcontext)) + { + return(False); + } + + if ( retval = krb5_timeofday(kcontext, &now) ) + { + return(False); + } + + if ( retval = krb5_cc_default(kcontext, &ccache) ) + { + return(False); + } + + if ( retval = krb5_parse_name(kcontext, this_user, &kprinc) ) + { + return(False); + } + + memset((char *)&kcreds, 0, sizeof(kcreds)); + + kcreds.client = kprinc; + + if ((retval = krb5_build_principal_ext(kcontext, &server, + krb5_princ_realm(kcontext, kprinc)->length, + krb5_princ_realm(kcontext, kprinc)->data, + tgtname.length, + tgtname.data, + krb5_princ_realm(kcontext, kprinc)->length, + krb5_princ_realm(kcontext, kprinc)->data, + 0))) + { + return(False); + } + + kcreds.server = server; + + retval = krb5_get_in_tkt_with_password(kcontext, + options, + addrs, + NULL, + preauth, + password, + 0, + &kcreds, + 0); + + if ( retval ) + { + return(False); + } + + return(True); +} +#endif /* KRB5_AUTH */ #ifdef LINUX_BIGCRYPT /**************************************************************************** @@ -687,6 +767,10 @@ Hence we make a direct return to avoid a second chance!!! if (dfs_auth(this_user,password)) return(True); #endif +#ifdef KRB5_AUTH + if (krb5_auth(this_user,password)) return(True); +#endif + #ifdef PWDAUTH if (pwdauth(this_user,password) == 0) return(True); @@ -1318,7 +1402,8 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) } file_host = strtok(bp, " \t\n"); file_user = strtok(NULL, " \t\n"); - DEBUG(7, ("check_user_equiv %s %s\n", file_host, file_user)); + DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)", + file_user ? file_user : "(null)" )); if (file_host && *file_host) { BOOL host_ok = False; -- cgit From a3de6a813ed058255f1e9b2da2aa181f5becc51f Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 22 Jul 1997 19:04:40 +0000 Subject: charset.c: Fixed signed/unsigned issues. password.c: Fixed problem with MS-Exchange services. Jeremy (jallison@whistle.com) (This used to be commit e723dd3deec00a91568c5aa546374409ce7ba379) --- source3/smbd/password.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e00028d87e..eb837c2584 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -153,12 +153,26 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) struct passwd *pwfile; /* for getting real name from passwd file */ int real_name_len; +#if 0 + /* + * After observing MS-Exchange services writing to a Samba share + * I belive this code is incorrect. Each service does it's own + * sessionsetup_and_X for the same user, and as each service shuts + * down, it does a user_logoff_and_X. As we are consolidating multiple + * sessionsetup_and_X's onto the same vuid here, when the first service + * shuts down, it invalidates all the open files for the other services. + * Hence I am removing this code and forcing each sessionsetup_and_X + * to get a new vuid. + * Jeremy Allison. (jallison@whistle.com). + */ + int i; for(i = 0; i < num_validated_users; i++) { vuser = &validated_users[i]; if( vuser->uid == uid ) return (uint16)(i + VUID_OFFSET); /* User already validated */ } +#endif validated_users = (user_struct *)Realloc(validated_users, sizeof(user_struct)* -- cgit From 7314126d9e1d84997d818166f27e2076d55ff04e Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Mon, 28 Jul 1997 18:59:57 +0000 Subject: client.c: Added amanda fixes. clitar.c: Added amanda fixes. nameannounce.c: Removed redundent code. nameelect.c: Removed redundent code. nameserv.h: Removed redundent code. nameservresp.c: Removed redundent code. namework.c: Removed redundent code. password.c: Prevented crash if getpwnam fails. Jeremy (jallison@whistle.com) (This used to be commit 760fe30353de66e8e6571f8ff4ec1064261b5428) --- source3/smbd/password.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index eb837c2584..23c29104e3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -237,13 +237,15 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) vuser->real_name = Realloc(vuser->real_name, 15); strcpy(vuser->real_name, "\0"); if (lp_unix_realname()) { - pwfile=getpwnam(vuser->name); - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); - real_name_len = strcspn(pwfile->pw_gecos, ","); - DEBUG(3, ("Real name length: %d\n", real_name_len)); - vuser->real_name = (char *)Realloc(vuser->real_name, real_name_len+1); - strncpy(vuser->real_name, pwfile->pw_gecos, real_name_len); - vuser->real_name[real_name_len]='\0'; + if((pwfile=getpwnam(vuser->name))!= NULL) + { + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); + real_name_len = strcspn(pwfile->pw_gecos, ","); + DEBUG(3, ("Real name length: %d\n", real_name_len)); + vuser->real_name = (char *)Realloc(vuser->real_name, real_name_len+1); + strncpy(vuser->real_name, pwfile->pw_gecos, real_name_len); + vuser->real_name[real_name_len]='\0'; + } } return (uint16)((num_validated_users - 1) + VUID_OFFSET); -- cgit From b5114b41f574c5a5341e07d6f16877a48c6b874d Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Tue, 5 Aug 1997 01:31:55 +0000 Subject: Makefile: Added IRIX 6 target. loadparm.c: Fixed stupid static warnings with set_default_server_announce_type. password.c: Fixed char -> uchar cast warnings. nameservreply.c: Fixed group fade out code. Jeremy (jallison@whistle.com) (This used to be commit a2dd5c5a551547e83c707e63c0696c7724035501) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 23c29104e3..67f32d376c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -54,7 +54,7 @@ void generate_next_challenge(char *challenge) v2 = (counter++) * getpid() + tval.tv_usec; SIVAL(challenge,0,v1); SIVAL(challenge,4,v2); - E1(challenge,"SAMBA",(char *)saved_challenge); + E1((uchar *)challenge,(uchar *)"SAMBA",(uchar *)saved_challenge); memcpy(challenge,saved_challenge,8); challenge_sent = True; } @@ -944,7 +944,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) DEBUG(4,("Checking NT MD4 password\n")); if(smb_password_check(password, smb_pass->smb_nt_passwd, - (char *)challenge)) + (unsigned char *)challenge)) { update_protected_database(user,True); return(True); @@ -957,7 +957,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) if (smb_password_check(password, smb_pass->smb_passwd, - (char *)challenge)) { + (unsigned char *)challenge)) { update_protected_database(user,True); return(True); } -- cgit From 9170cfd4b6455a235e7600e7988f34d77693e7ed Mon Sep 17 00:00:00 2001 From: Samba Release Account Date: Mon, 11 Aug 1997 18:06:44 +0000 Subject: spelling. lkcl (This used to be commit 7e326450cf5aeee704df9fb5e298b0fc353dfb8b) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 67f32d376c..2740304cc4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1225,7 +1225,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password)); #endif - /* there are several possabilities: + /* there are several possibilities: 1) login as the given user with given password 2) login as a previously registered username with the given password 3) login as a session list username with the given password -- cgit From ab68ac375ee5c175366123617887a725498efddc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 4 Sep 1997 21:23:27 +0000 Subject: 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. Jeremy (jallison@whistle.com) (This used to be commit ebf9487a9a68c4d786449490627ee919622e6dbf) --- source3/smbd/password.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2740304cc4..ed79d658a6 100644 --- a/source3/smbd/password.c +++ b/source3/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; -- cgit From 33a003de4056532be0c9a199d4857b9da1b18034 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Sep 1997 16:37:18 +0000 Subject: This commit does 3 main things: 1) put the encryption code in by default, with no #ifdef. It is still disabled by default so you need to add "encrypt passwords = yes" in smb.conf but at least all binaries will have it. 2) cleanup the kanji code so it compiles with no warnings 3) get rid of lots of uses of ugly non-portable C code. The main offender being things like "register" but also remove uses of the "const" keyword as there are compilers out there that don't support it and even those that do often complain about its usage. Users don't like warnings :-( There is still some work to do. We need to replace the md4 code with our own implementation. The current code (from rfc1186) is PD but is not very portable. The new RFC (rfc1320) is more portable but adds copyright restrictions. I'll do a from-scratch MD4 soon. We also need to test that what I've implemented is portable. It should be, but I'm too tired right now to test it on anything other than intel linux. (This used to be commit db917c62c14315afe6f0745a8097c1bca25cbf07) --- source3/smbd/password.c | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ed79d658a6..abecb46dcd 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -36,7 +36,6 @@ static char this_user[100]=""; static char this_salt[100]=""; static char this_crypted[100]=""; -#ifdef SMB_PASSWD /* Data to do lanman1/2 password challenge. */ static unsigned char saved_challenge[8]; static BOOL challenge_sent=False; @@ -78,7 +77,6 @@ BOOL last_challenge(char *challenge) memcpy(challenge,saved_challenge,8); return(True); } -#endif /* this holds info on user ids that are already validated for this VC */ static user_struct *validated_users = NULL; @@ -401,7 +399,7 @@ static char *PAM_password; * echo off means password. */ static int PAM_conv (int num_msg, - const struct pam_message **msg, + struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int count = 0, replies = 0; @@ -812,7 +810,6 @@ Hence we make a direct return to avoid a second chance!!! #endif } -#ifdef SMB_PASSWD /**************************************************************************** core of smb password checking routine. ****************************************************************************/ @@ -854,7 +851,6 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha #endif return (memcmp(p24, password, 24) == 0); } -#endif /**************************************************************************** check if a username/password is OK @@ -864,21 +860,16 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) pstring pass2; int level = lp_passwordlevel(); struct passwd *pass; -#ifdef SMB_PASSWD char challenge[8]; struct smb_passwd *smb_pass; BOOL challenge_done = False; -#endif if (password) password[pwlen] = 0; -#ifdef SMB_PASSWD if (pwlen == 24) challenge_done = last_challenge(challenge); -#endif #if DEBUG_PASSWORD -#ifdef SMB_PASSWD if (challenge_done) { int i; @@ -886,10 +877,9 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) for( i = 0; i < 24; i++) DEBUG(100,("%0x ", (unsigned char)password[i])); DEBUG(100,("]\n")); + } else { + DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password)); } - else -#endif - DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password)); #endif if (!password) @@ -906,8 +896,6 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) else pass = Get_Pwnam(user,True); -#ifdef SMB_PASSWD - DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done)); if((pwlen == 24) && challenge_done) @@ -964,7 +952,6 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) DEBUG(3,("Error smb_password_check failed\n")); } -#endif DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen)); @@ -1587,12 +1574,12 @@ BOOL server_cryptkey(char *buf) 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,' '); + char buf2[32]; /* create name as PIDname */ + sprintf(buf2,"%d", getpid()); + strncpy(&buf2[strlen(buf2)], remote_machine, 31 - strlen(buf2)); + buf2[31] = '\0'; + DEBUG(1,("negprot w/password server as %s\n",buf2)); + name_mangle(buf2,p,' '); len += name_len(p); } -- cgit From 57c2578cb2b7e02acc6c04d07adc11a77c40aa9c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Sep 1997 04:41:16 +0000 Subject: - change generate_challenge() to use md4 instead of des - move routines about a bit between smbencrypt.c and smbdes.c. Ensure that there is no entry point for normal DES operation - add the following comment: This code is NOT a complete DES implementation. It implements only the minimum necessary for SMB authentication, as used by all SMB products (including every copy of Microsoft Windows95 ever sold) In particular, it can only do a unchained forward DES pass. This means it is not possible to use this code for encryption/decryption of data, instead it is only useful as a "hash" algorithm. There is no entry point into this code that allows normal DES operation. I believe this means that this code does not come under ITAR regulations but this is NOT a legal opinion. If you are concerned about the applicability of ITAR regulations to this code then you should confirm it for yourself (and maybe let me know if you come up with a different answer to the one above) (This used to be commit 35b92e725f351c9a9f2846a6b55f71c234f187c7) --- source3/smbd/password.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index abecb46dcd..7b581d1289 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -45,17 +45,24 @@ Get the next challenge value - no repeats. ********************************************************************/ void generate_next_challenge(char *challenge) { - static int counter = 0; - struct timeval tval; - int v1,v2; - GetTimeOfDay(&tval); - v1 = (counter++) + getpid() + tval.tv_sec; - v2 = (counter++) * getpid() + tval.tv_usec; - SIVAL(challenge,0,v1); - SIVAL(challenge,4,v2); - E1((uchar *)challenge,(uchar *)"SAMBA",(uchar *)saved_challenge); - memcpy(challenge,saved_challenge,8); - challenge_sent = True; + unsigned char buf[16]; + static int counter = 0; + struct timeval tval; + int v1,v2; + + /* get a sort-of random number */ + GetTimeOfDay(&tval); + v1 = (counter++) + getpid() + tval.tv_sec; + v2 = (counter++) * getpid() + tval.tv_usec; + SIVAL(challenge,0,v1); + SIVAL(challenge,4,v2); + + /* mash it up with md4 */ + mdfour(buf, challenge, 8); + + memcpy(saved_challenge, buf, 8); + memcpy(challenge,buf,8); + challenge_sent = True; } /******************************************************************* -- cgit From cda707f9176c2bb433b5cc4968a9617005f8dc00 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 16 Sep 1997 08:26:33 +0000 Subject: add a cast (This used to be commit e712c6ed61abeae5ec2acf99f109ad81e7a19978) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 7b581d1289..35f73eab2d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -58,7 +58,7 @@ void generate_next_challenge(char *challenge) SIVAL(challenge,4,v2); /* mash it up with md4 */ - mdfour(buf, challenge, 8); + mdfour(buf, (unsigned char *)challenge, 8); memcpy(saved_challenge, buf, 8); memcpy(challenge,buf,8); -- cgit From a0cd12e221af54e00aa7dd971c080881da8b32ac Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 30 Sep 1997 02:38:19 +0000 Subject: dir.c: more pstrcpys. local.h: Add OPLOCK_BREAK_TIMEOUT. password.c: Fix for paranoia password server security bug. proto.h: Updated. reply.c: Oplock changes. server.c: Massive oplock changes - nearly there.... smb.h: oplock definitions. util.c: Add local message processing queues for oplocks. Jeremy (jallison@whistle.com) (This used to be commit 92f1553db2cdf6f32881eb984a87050cf3e4760b) --- source3/smbd/password.c | 45 +++++++++++++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 14 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 35f73eab2d..f4d94791cf 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1504,13 +1504,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; @@ -1519,6 +1520,14 @@ BOOL server_cryptkey(char *buf) struct in_addr dest_ip; 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); @@ -1530,7 +1539,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)) { @@ -1596,8 +1605,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); @@ -1618,21 +1627,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")); @@ -1644,15 +1653,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 */ @@ -1662,18 +1679,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 From c5e739febe5ab3bcc5d147fe791c788ec72531a3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Oct 1997 14:48:05 +0000 Subject: Makefile: added credentials.c to smbd credentials.c: using credential structures instead of char* password.c uid.c server.c: added sid and attr to user_struct. smbdes.c: smbhash and str_to_key make public instead of private. pipes.c smb.h: lsa structures, sub-functions. proto.h: usual. (This used to be commit 87a0a944855a673d693d934e446bdc231b1c7f02) --- source3/smbd/password.c | 97 ++++++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 45 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f4d94791cf..af9be289c7 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -96,10 +96,10 @@ tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ user_struct *get_valid_user_struct(uint16 vuid) { - if(vuid == UID_FIELD_INVALID) + if (vuid == UID_FIELD_INVALID) return NULL; vuid -= VUID_OFFSET; - if((vuid >= (uint16)num_validated_users) || + if ((vuid >= (uint16)num_validated_users) || (validated_users[vuid].uid == -1) || (validated_users[vuid].gid == -1)) return NULL; return &validated_users[vuid]; @@ -111,19 +111,28 @@ invalidate a uid void invalidate_vuid(uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); - if(vuser == 0) - return; + + if (vuser == NULL) return; vuser->uid = -1; vuser->gid = -1; - vuser->user_ngroups = 0; - if(vuser->user_groups && - (vuser->user_groups != (gid_t *)vuser->user_igroups)) - free(vuser->user_groups); - vuser->user_groups = NULL; - if(vuser->user_igroups) - free(vuser->user_igroups); - vuser->user_igroups = NULL; + + vuser->n_sids = 0; + + /* same number of igroups as groups as attrs */ + vuser->n_groups = 0; + + if (vuser->groups && (vuser->groups != (gid_t *)vuser->igroups)) + free(vuser->groups); + + if (vuser->igroups) free(vuser->igroups); + if (vuser->attrs ) free(vuser->attrs); + if (vuser->sids ) free(vuser->sids); + + vuser->attrs = NULL; + vuser->sids = NULL; + vuser->igroups = NULL; + vuser->groups = NULL; } @@ -133,7 +142,7 @@ return a validated username char *validated_username(uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); - if(vuser == 0) + if (vuser == NULL) return 0; return(vuser->name); } @@ -156,12 +165,11 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) int home_server_len; #endif struct passwd *pwfile; /* for getting real name from passwd file */ - int real_name_len; #if 0 /* * After observing MS-Exchange services writing to a Samba share - * I belive this code is incorrect. Each service does it's own + * I belive this code is incorrect. Each service does its own * sessionsetup_and_X for the same user, and as each service shuts * down, it does a user_logoff_and_X. As we are consolidating multiple * sessionsetup_and_X's onto the same vuid here, when the first service @@ -174,7 +182,7 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) int i; for(i = 0; i < num_validated_users; i++) { vuser = &validated_users[i]; - if( vuser->uid == uid ) + if ( vuser->uid == uid ) return (uint16)(i + VUID_OFFSET); /* User already validated */ } #endif @@ -198,16 +206,21 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) vuser->guest = guest; strcpy(vuser->name,name); - vuser->user_ngroups = 0; - vuser->user_groups = NULL; - vuser->user_igroups = NULL; + vuser->n_sids = 0; + vuser->sids = NULL; + + vuser->n_groups = 0; + vuser->groups = NULL; + vuser->igroups = NULL; + vuser->attrs = NULL; /* Find all the groups this uid is in and store them. Used by become_user() */ setup_groups(name,uid,gid, - &vuser->user_ngroups, - &vuser->user_igroups, - &vuser->user_groups); + &vuser->n_groups, + &vuser->igroups, + &vuser->groups, + &vuser->attrs); DEBUG(3,("uid %d registered to name %s\n",uid,name)); @@ -215,14 +228,14 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) vuser->home_share = NULL; DEBUG(3, ("Setting default HOMESHR to: \\\\logon server\\HOMES\n")); vuser->home_share = Realloc(vuser->home_share, 32); - strcpy(vuser->home_share,"\\\\%L\\HOMES"); + strcpy(vuser->home_share,"\\\\%L\\%U"); - if (nis_error = yp_get_default_domain(&nis_domain)) + if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); DEBUG(3, ("NIS Domain: %s\n", nis_domain)); - if (nis_error = yp_match(nis_domain, nis_map, vuser->name, strlen(vuser->name), - &nis_result, &nis_result_len)) + if ((nis_error = yp_match(nis_domain, nis_map, vuser->name, strlen(vuser->name), + &nis_result, &nis_result_len)) != 0) DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); if (!nis_error && lp_nis_home_map()) { home_server_len = strcspn(nis_result,":"); @@ -237,19 +250,13 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) } #endif - vuser->real_name = NULL; DEBUG(3, ("Clearing default real name\n")); - vuser->real_name = Realloc(vuser->real_name, 15); - strcpy(vuser->real_name, "\0"); + fstrcpy(vuser->real_name, "\0"); if (lp_unix_realname()) { - if((pwfile=getpwnam(vuser->name))!= NULL) + if ((pwfile=getpwnam(vuser->name))!= NULL) { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); - real_name_len = strcspn(pwfile->pw_gecos, ","); - DEBUG(3, ("Real name length: %d\n", real_name_len)); - vuser->real_name = (char *)Realloc(vuser->real_name, real_name_len+1); - strncpy(vuser->real_name, pwfile->pw_gecos, real_name_len); - vuser->real_name[real_name_len]='\0'; + fstrcpy(vuser->real_name, pwfile->pw_gecos); } } @@ -702,7 +709,7 @@ static int linux_bigcrypt(char *password,char *salt1, char *crypted) for ( i=strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) { char * p = crypt(password,salt) + 2; - if(strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0) + if (strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0) return(0); password += LINUX_PASSWORD_SEG_CHARS; crypted += strlen(p); @@ -826,10 +833,10 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha unsigned char p21[21]; unsigned char p24[24]; - if(part_passwd == NULL) + if (part_passwd == NULL) DEBUG(10,("No password set - allowing access\n")); /* No password set - always true ! */ - if(part_passwd == NULL) + if (part_passwd == NULL) return 1; memset(p21,'\0',21); @@ -905,7 +912,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done)); - if((pwlen == 24) && challenge_done) + if ((pwlen == 24) && challenge_done) { DEBUG(4,("Checking SMB password for user %s (l=24)\n",user)); @@ -916,28 +923,28 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) } smb_pass = get_smbpwnam(user); - if(!smb_pass) + if (!smb_pass) { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); return(False); } /* Ensure the uid's match */ - if(smb_pass->smb_userid != pass->pw_uid) + if (smb_pass->smb_userid != pass->pw_uid) { DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); return(False); } - if(Protocol >= PROTOCOL_NT1) + if (Protocol >= PROTOCOL_NT1) { /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). */ - if(smb_pass->smb_nt_passwd != NULL) + if (smb_pass->smb_nt_passwd != NULL) { DEBUG(4,("Checking NT MD4 password\n")); - if(smb_password_check(password, + if (smb_password_check(password, smb_pass->smb_nt_passwd, (unsigned char *)challenge)) { @@ -1080,7 +1087,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) } /* give up? */ - if(level < 1) + if (level < 1) { update_protected_database(user,False); -- cgit From 91e56c7b7b5b1a72dc00b468204c007820d3460e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 15 Oct 1997 04:04:38 +0000 Subject: force the salt to be a maximum of 2 characters long in calls to crypt() This might solve some password problems, particulary on HPUX (This used to be commit 45f4ae4327a8836cad22bbf64f1effba6a6eb7f5) --- source3/smbd/password.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index af9be289c7..1b1bd34bcc 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1047,6 +1047,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) /* extract relevant info */ strcpy(this_user,pass->pw_name); strcpy(this_salt,pass->pw_passwd); + this_salt[2] = 0; strcpy(this_crypted,pass->pw_passwd); if (!*this_crypted) { -- cgit From b676826bec7cef3a1c324e0e655588195e80c1c5 Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Thu, 16 Oct 1997 05:33:24 +0000 Subject: Added Michael Johnsons' PAM modifications This patch has been checked over. JHT (This used to be commit c84a043f89ccba001597962cd03e2f2a634c4b08) --- source3/smbd/password.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1b1bd34bcc..9f4f0abcae 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -416,33 +416,33 @@ static int PAM_conv (int num_msg, struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { - int count = 0, replies = 0; + int replies = 0; struct pam_response *reply = NULL; - int size = sizeof(struct pam_response); - #define GET_MEM if (reply) realloc(reply, size); else reply = malloc(size); \ - if (!reply) return PAM_CONV_ERR; \ - size += sizeof(struct pam_response) #define COPY_STRING(s) (s) ? strdup(s) : NULL - for (count = 0; count < num_msg; count++) { - switch (msg[count]->msg_style) { + reply = malloc(sizeof(struct pam_response) * num_msg); + if (!reply) return PAM_CONV_ERR; + + for (replies = 0; replies < num_msg; replies++) { + switch (msg[replies]->msg_style) { case PAM_PROMPT_ECHO_ON: - GET_MEM; reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies++].resp = COPY_STRING(PAM_username); + reply[replies].resp = COPY_STRING(PAM_username); /* PAM frees resp */ break; case PAM_PROMPT_ECHO_OFF: - GET_MEM; reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies++].resp = COPY_STRING(PAM_password); + reply[replies].resp = COPY_STRING(PAM_password); /* PAM frees resp */ break; case PAM_TEXT_INFO: + /* fall through */ + case PAM_ERROR_MSG: /* ignore it... */ + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = NULL; break; - case PAM_ERROR_MSG: default: /* Must be an error of some sort... */ free (reply); -- cgit From f4b4b3e6e35916dc5e280542f5f914e40b25dd21 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Oct 1997 02:50:12 +0000 Subject: casting cleanups (This used to be commit ab849a97821c9e1f199eea8ea2ec477687bed947) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9f4f0abcae..2da8a8f936 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1657,7 +1657,7 @@ BOOL server_cryptkey(char *buf) } /**************************************************************************** -attempted support for server level security +support for server level security ****************************************************************************/ BOOL server_validate(char *buf) { -- cgit From 423a7c417136af3f6d09b3c1763336dd0a401d4f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 20 Oct 1997 12:10:58 +0000 Subject: util.c password.c : added automount_server() function which, if -DAUTOMOUNT is in use, returns the server name of the NIS auto.map entry. otherwise, it returns local_server. added use of automount_server() for a new substitution %N for NIS home server. this defaults, via automount_server(), to the same functionality as %L if -DAUTOMOUNT is not used. removed vuser->home_share. moved code that grabbed the servername into the separate function automount_server(). loadparm.c : created "logon drive" (default of "") created "logon home" (default of "\\%N\%U") changed default of "logon path" from NULL to "\\%N\%U\profile". ipc.c pipenetlog.c : use lp_logon_drive(), lp_logon_home() and lp_logon_path() in their now easier-to-use form (don't have to check if *lp_logon_path() and manually substitute a default of \\%L\%U and do a standard_sub_basic() on the result, because the default automatically does this. (This used to be commit c6c28a4c3c9010ff9d5eac4bad091189a786d5a0) --- source3/smbd/password.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2da8a8f936..311ef47679 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -155,15 +155,6 @@ tell random client vuid's (normally zero) from valid vuids. uint16 register_vuid(int uid,int gid, char *name,BOOL guest) { user_struct *vuser; - -#if (defined(NETGROUP) && defined (AUTOMOUNT)) - int nis_error; /* returned by yp all functions */ - char *nis_result; /* yp_match inits this */ - int nis_result_len; /* and set this */ - char *nis_domain; /* yp_get_default_domain inits this */ - char *nis_map = (char *)lp_nis_home_map_name(); - int home_server_len; -#endif struct passwd *pwfile; /* for getting real name from passwd file */ #if 0 @@ -224,32 +215,6 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) DEBUG(3,("uid %d registered to name %s\n",uid,name)); -#if (defined(NETGROUP) && defined (AUTOMOUNT)) - vuser->home_share = NULL; - DEBUG(3, ("Setting default HOMESHR to: \\\\logon server\\HOMES\n")); - vuser->home_share = Realloc(vuser->home_share, 32); - strcpy(vuser->home_share,"\\\\%L\\%U"); - - if ((nis_error = yp_get_default_domain(&nis_domain)) != 0) - DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); - DEBUG(3, ("NIS Domain: %s\n", nis_domain)); - - if ((nis_error = yp_match(nis_domain, nis_map, vuser->name, strlen(vuser->name), - &nis_result, &nis_result_len)) != 0) - DEBUG(3, ("YP Error: %s\n", yperr_string(nis_error))); - if (!nis_error && lp_nis_home_map()) { - home_server_len = strcspn(nis_result,":"); - DEBUG(3, ("NIS lookup succeeded\n\tHome server length: %d\n",home_server_len)); - vuser->home_share = (char *)Realloc(vuser->home_share, home_server_len+12); - DEBUG(3, ("\tAllocated %d bytes for HOMESHR\n",home_server_len+12 )); - strcpy(vuser->home_share,"\\\\"); - strncat(vuser->home_share, nis_result, home_server_len); - strcat(vuser->home_share,"\\homes"); - DEBUG(2,("\tUser = %s\n\tUID = %d\n\tNIS result = %s\n\tHOMESHR = %s\n", - vuser->name, vuser->uid, nis_result, vuser->home_share)); - } -#endif - DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->real_name, "\0"); if (lp_unix_realname()) { -- cgit From 0891bb6a910841455162876be09a92107cd9df00 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 21 Oct 1997 09:34:33 +0000 Subject: rewrote the password server code using the new clientgen.c client interface The new code uses a source netbios name equal to the Samba servers name, not the client name. It also uses NetWkstaUserLogon to do a full network logon. This means it will honour the servers logon restrictions (such as login times etc). (This used to be commit 11de90f972f6d83974425e80014f54e15d495413) --- source3/smbd/password.c | 275 +++++++++++++++++++----------------------------- 1 file changed, 106 insertions(+), 169 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 311ef47679..24ee52ed69 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1475,206 +1475,143 @@ BOOL check_hosts_equiv(char *user) } -int password_client = -1; -static fstring pserver; -static char *secserver_inbuf = NULL; +static struct cli_state cli; /**************************************************************************** -attempted support for server level security +return the client state structure ****************************************************************************/ -BOOL server_cryptkey(char *buf) +struct cli_state *server_client(void) { - pstring outbuf; - fstring pass_protocol; - extern fstring remote_machine; - char *p; - int len; - fstring desthost; - struct in_addr dest_ip; - 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; - - if (Protocol < PROTOCOL_NT1) { - strcpy(pass_protocol,"LM1.2X002"); - } else { - strcpy(pass_protocol,"NT LM 0.12"); - } - - bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN); - bzero(outbuf,sizeof(outbuf)); - - for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { - strcpy(desthost,p); - standard_sub_basic(desthost); - strupper(desthost); - - dest_ip = *interpret_addr2(desthost); - if (zero_ip(dest_ip)) { - DEBUG(1,("Can't resolve address for %s\n",p)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",p)); - continue; - } - - password_client = open_socket_out(SOCK_STREAM, &dest_ip, port, SHORT_CONNECT_TIMEOUT); - if (password_client >= 0) { - DEBUG(3,("connected to password server %s\n",p)); - StrnCpy(pserver,p,sizeof(pserver)-1); - break; - } - } - - if (password_client < 0) { - DEBUG(1,("password server not available\n")); - return(False); - } - - - /* send a session request (RFC 8002) */ - - /* put in the destination name */ - len = 4; - p = outbuf+len; - name_mangle(desthost,p,' '); - len += name_len(p); - p = outbuf+len; - - /* and my name */ - /* 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 buf2[32]; /* create name as PIDname */ - sprintf(buf2,"%d", getpid()); - strncpy(&buf2[strlen(buf2)], remote_machine, 31 - strlen(buf2)); - buf2[31] = '\0'; - DEBUG(1,("negprot w/password server as %s\n",buf2)); - name_mangle(buf2,p,' '); - len += name_len(p); - } - - _smb_setlen(outbuf,len); - CVAL(outbuf,0) = 0x81; - - send_smb(password_client,outbuf); - - - 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); - } + return &cli; +} - DEBUG(3,("got session\n")); +/**************************************************************************** +support for server level security +****************************************************************************/ +struct cli_state *server_cryptkey(void) +{ + fstring desthost; + struct in_addr dest_ip; + extern fstring local_machine; + char *p; + + if (!cli_initialise(&cli)) + return NULL; + + for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { + fstrcpy(desthost,p); + standard_sub_basic(desthost); + strupper(desthost); + + dest_ip = *interpret_addr2(desthost); + if (zero_ip(dest_ip)) { + DEBUG(1,("Can't resolve address for %s\n",p)); + continue; + } - bzero(outbuf,smb_size); + if (ismyip(dest_ip)) { + DEBUG(1,("Password server loop - disabling password server %s\n",p)); + continue; + } - /* setup the protocol string */ - set_message(outbuf,0,strlen(pass_protocol)+2,True); - p = smb_buf(outbuf); - *p++ = 2; - strcpy(p,pass_protocol); + if (cli_connect(&cli, desthost, &dest_ip)) { + DEBUG(3,("connected to password server %s\n",p)); + break; + } + } - CVAL(outbuf,smb_com) = SMBnegprot; - CVAL(outbuf,smb_flg) = 0x8; - SSVAL(outbuf,smb_flg2,0x1); + if (!p) { + DEBUG(1,("password server not available\n")); + cli_shutdown(&cli); + return NULL; + } - send_smb(password_client,outbuf); - ret = receive_smb(password_client,secserver_inbuf,5000); + if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { + DEBUG(1,("%s rejected the session\n",desthost)); + cli_shutdown(&cli); + return NULL; + } - 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); - } + DEBUG(3,("got session\n")); - 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); - } + if (!cli_negprot(&cli)) { + DEBUG(1,("%s rejected the negprot\n",desthost)); + cli_shutdown(&cli); + return NULL; + } - memcpy(buf,secserver_inbuf,smb_len(secserver_inbuf)+4); + if (cli.protocol < PROTOCOL_LANMAN2 || + !(cli.sec_mode & 1)) { + DEBUG(1,("%s isn't in user level security mode\n",desthost)); + cli_shutdown(&cli); + return NULL; + } - DEBUG(3,("password server OK\n")); + DEBUG(3,("password server OK\n")); - return(True); + return &cli; } /**************************************************************************** -support for server level security +validate a password with the password server ****************************************************************************/ -BOOL server_validate(char *buf) +BOOL server_validate(char *user, char *domain, + char *pass, int passlen, + char *ntpass, int ntpasslen) { - pstring outbuf; - BOOL ret; + extern fstring local_machine; + fstring share; - 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 (!cli.initialised) { + DEBUG(1,("password server %s is not connected\n", cli.desthost)); + return(False); + } - if (password_client < 0) { - DEBUG(1,("%s not connected\n",pserver)); - return(False); - } + if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", cli.desthost)); + return False; + } - bzero(secserver_inbuf,BUFFER_SIZE + SAFETY_MARGIN); - memcpy(outbuf,buf,sizeof(outbuf)); + /* if logged in as guest then reject */ + if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); + return(False); + } - /* send a session setup command */ - CVAL(outbuf,smb_flg) = 0x8; - SSVAL(outbuf,smb_flg2,0x1); - CVAL(outbuf,smb_vwv0) = 0xFF; - set_message(outbuf,smb_numwords(outbuf),smb_buflen(outbuf),False); + sprintf(share,"\\\\%s\\IPC$", cli.desthost); - SCVAL(secserver_inbuf,smb_rcls,1); + if (!cli_send_tconX(&cli, share, "IPC", "", 1)) { + DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); + return False; + } - send_smb(password_client,outbuf); - ret = receive_smb(password_client,secserver_inbuf,5000); - if (!ret || CVAL(secserver_inbuf,smb_rcls) != 0) { - DEBUG(1,("password server %s rejected the password\n",pserver)); - return(False); - } + if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { + DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); + cli_tdis(&cli); + return False; + } - /* if logged in as guest then reject */ - if ((SVAL(secserver_inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n",pserver)); - return(False); - } + if (cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); + cli_tdis(&cli); + return False; + } + + if (!strequal(cli.eff_name, user)) { + DEBUG(1,("password server %s gave different username %s\n", + cli.desthost, + cli.eff_name)); + cli_tdis(&cli); + return False; + } - DEBUG(3,("password server %s accepted the password\n",pserver)); + DEBUG(3,("password server %s accepted the password\n", cli.desthost)); -#if !KEEP_PASSWORD_SERVER_OPEN - close(password_client); password_client= -1; -#endif + cli_tdis(&cli); - return(True); + return(True); } -- cgit From 224c40a52335bf1afc7662183900e143307aa5be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 1 Nov 1997 13:22:16 +0000 Subject: a simple SMB torture tester. This will allow us to evaluate locking techniques more accurately. (This used to be commit 054e3b2ae3a8cfb98fde72becef9b05de34d2ba7) --- source3/smbd/password.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 24ee52ed69..b759f68430 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1560,7 +1560,6 @@ BOOL server_validate(char *user, char *domain, char *ntpass, int ntpasslen) { extern fstring local_machine; - fstring share; if (!cli.initialised) { DEBUG(1,("password server %s is not connected\n", cli.desthost)); @@ -1579,9 +1578,7 @@ BOOL server_validate(char *user, char *domain, } - sprintf(share,"\\\\%s\\IPC$", cli.desthost); - - if (!cli_send_tconX(&cli, share, "IPC", "", 1)) { + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); return False; } -- cgit From bd529d7a83c35be233baca09bc79aa911ad443ce Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 6 Nov 1997 23:03:58 +0000 Subject: following a cvs error, i am rewriting this monster-commit. with bad grace. Modified Files: --------------- Makefile: adding extra files ipc.c : send_trans_reply() - alignment issue. this makes the alignment the same as that in NT. this should be looked at by people who understand the SMB stuff better than i. api_fd_commands[] - added samr and wkssvc pipes. loadparm.c : lp_domain_controller() changed to mean "samba is a domain controller". it's a "yes/no" parameter, now. no, it isn't used _anywhere_. namedbwork.c nameelect.c : if "domain controller = yes" then add SV_TYPE_DOMAIN_CTRL to the host _and_ workgroup announcements. yes, you must do both: nt does. namelogon.c : important NETLOGON bug in SAMLOGON request parsing, which may be the source of some people's problems with logging on to the Samba PDC. password.c : get_smbpwnam() renamed to get_smbpwd_entry(). pipes.c : added samr and wkssvc pipes. proto.h : usual. can we actually _remove_ proto.h from the cvs tree, and have it as one of the Makefile dependencies, or something? reply.c : get_smbpwnam() renamed to get_smbpwd_entry() - also changed response error code when logging in from a WORKSTATION$ account. yes, paul is right: we need to know when to return the right error code, and why. server.c : added call to reset_chain_pnum(). #ifdef NTDOMAIN added call to init_lsa_policy_hnd() #endif. jeremy, you'd be proud: i did a compile without NTDOMAIN, and caught a link error for this function. smb.h : defines and structures for samr and wkssvc pipes. smbpass.c : modified get_smbpwnam() to get_smbpwd_entry() and it now takes two arguments. one for the name; if this is null, it looks up by smb_userid instead. oh, by the way, smb_userids are actually domain relative ids (RIDs). concatenate a RID with the domain SID, and you have an internet globally unique way of identifying a user. we're using RIDs in the wrong way.... added mod_smbpwnam() function. this was based on code in smbpasswd.c rpc_pipes/lsaparse.c : added enum trusted domain parsing. this is incomplete: i need a packet trace to write it properly. rpc_pipes/pipe_hnd.c : added reset_chain_pnum() function. rpc_pipes/pipenetlog.c : get_smbpwnam() function renamed to get_smbpwd_entry(). arcfour() issues. removed capability of get_md4pw() function to automatically add workstation accounts. this should either be done using smbpasswd -add MACHINE$, or by using \PIPE\samr. rpc_pipes/pipe_util.c : create_pol_hnd() - creates a unique LSA Policy Handle. overkill function: uses a 64 bit sequence number; current unix time and the smbd pid. rpc_pipes/smbparse.c : arcfour() issues. smb_io_unistr2() should advance by uni_str_len not uni_max_len. smb_io_smb_hdr_rb() - request bind uses uint16 for the context id, and uint8 for the num_syntaxes. oops, i put these both as uint32s. Added Files: ------------ rpc_pipes/lsa_hnd.c : on the samr pipe, allocate and associate an LSA Policy Handle with a SID. you receive queries with the LSA Policy Handle, and have to turn this back into a SID in order to answer the query... rpc_pipes/pipesamr.c rpc_pipes/samrparse.c \PIPE\samr processing. samr i presume is the SAM Replication pipe. rpc_pipes/pipewkssvc.c rpc_pipes/wksparse.c \PIPE\wkssvc processing. the Workstation Service pipe? holy cow. (This used to be commit 1bd084b3e690eb26a1006d616075e53d711ecd2f) --- source3/smbd/password.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b759f68430..185fc68f5a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -887,7 +887,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - smb_pass = get_smbpwnam(user); + /* non-null username indicates search by username not smb userid */ + smb_pass = get_smbpwd_entry(user, 0); if (!smb_pass) { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); -- cgit From e357d9106895b165bfa3f8331b9f186004c9a6cd Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 9 Nov 1997 17:30:10 +0000 Subject: attempting to mark up 32 bit error codes, needed for NT domains. separated out smb server-mode password validation into a separate file. added called and calling netbios names to client gen state: referenced section in rfc1002.txt. created workstation trust account checking code in ntclient.c there might be a bug in reply_session_setup_andX. i indented and added { } around single-line if statements: the lm password checking code now doesn't look right (around the GUEST_SESSSETUP bits). *no code semantics have been changed by the indentation process*. (This used to be commit f27966957fa7f16d337a4a58719239d036deab4c) --- source3/smbd/password.c | 140 +----------------------------------------------- 1 file changed, 1 insertion(+), 139 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 185fc68f5a..7dd2133406 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,7 @@ #include "includes.h" -#if (defined(NETGROUP) && defined (AUTOMOUNT)) +#ifdef NETGROUP #include "rpcsvc/ypclnt.h" #endif @@ -1475,141 +1475,3 @@ BOOL check_hosts_equiv(char *user) return(False); } - -static struct cli_state cli; - -/**************************************************************************** -return the client state structure -****************************************************************************/ -struct cli_state *server_client(void) -{ - return &cli; -} - -/**************************************************************************** -support for server level security -****************************************************************************/ -struct cli_state *server_cryptkey(void) -{ - fstring desthost; - struct in_addr dest_ip; - extern fstring local_machine; - char *p; - - if (!cli_initialise(&cli)) - return NULL; - - for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { - fstrcpy(desthost,p); - standard_sub_basic(desthost); - strupper(desthost); - - dest_ip = *interpret_addr2(desthost); - if (zero_ip(dest_ip)) { - DEBUG(1,("Can't resolve address for %s\n",p)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",p)); - continue; - } - - if (cli_connect(&cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",p)); - break; - } - } - - if (!p) { - DEBUG(1,("password server not available\n")); - cli_shutdown(&cli); - return NULL; - } - - if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { - DEBUG(1,("%s rejected the session\n",desthost)); - cli_shutdown(&cli); - return NULL; - } - - DEBUG(3,("got session\n")); - - if (!cli_negprot(&cli)) { - DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(&cli); - return NULL; - } - - if (cli.protocol < PROTOCOL_LANMAN2 || - !(cli.sec_mode & 1)) { - DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(&cli); - return NULL; - } - - DEBUG(3,("password server OK\n")); - - return &cli; -} - -/**************************************************************************** -validate a password with the password server -****************************************************************************/ -BOOL server_validate(char *user, char *domain, - char *pass, int passlen, - char *ntpass, int ntpasslen) -{ - extern fstring local_machine; - - if (!cli.initialised) { - DEBUG(1,("password server %s is not connected\n", cli.desthost)); - return(False); - } - - if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli.desthost)); - return False; - } - - /* if logged in as guest then reject */ - if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); - return(False); - } - - - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); - return False; - } - - - if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); - cli_tdis(&cli); - return False; - } - - if (cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); - cli_tdis(&cli); - return False; - } - - if (!strequal(cli.eff_name, user)) { - DEBUG(1,("password server %s gave different username %s\n", - cli.desthost, - cli.eff_name)); - cli_tdis(&cli); - return False; - } - - DEBUG(3,("password server %s accepted the password\n", cli.desthost)); - - cli_tdis(&cli); - - return(True); -} - - -- cgit From 77aec4ae6307c0ad0b843bbf23d64ccb1aaf7476 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 10 Nov 1997 19:23:17 +0000 Subject: Rolled back tree state to 11:59pm 8th November 1997 EST to remove problems. Jeremy (This used to be commit 4a36ac236c2ad634f05efcd0179875d09988614a) --- source3/smbd/password.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 7dd2133406..185fc68f5a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,7 @@ #include "includes.h" -#ifdef NETGROUP +#if (defined(NETGROUP) && defined (AUTOMOUNT)) #include "rpcsvc/ypclnt.h" #endif @@ -1475,3 +1475,141 @@ BOOL check_hosts_equiv(char *user) return(False); } + +static struct cli_state cli; + +/**************************************************************************** +return the client state structure +****************************************************************************/ +struct cli_state *server_client(void) +{ + return &cli; +} + +/**************************************************************************** +support for server level security +****************************************************************************/ +struct cli_state *server_cryptkey(void) +{ + fstring desthost; + struct in_addr dest_ip; + extern fstring local_machine; + char *p; + + if (!cli_initialise(&cli)) + return NULL; + + for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { + fstrcpy(desthost,p); + standard_sub_basic(desthost); + strupper(desthost); + + dest_ip = *interpret_addr2(desthost); + if (zero_ip(dest_ip)) { + DEBUG(1,("Can't resolve address for %s\n",p)); + continue; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("Password server loop - disabling password server %s\n",p)); + continue; + } + + if (cli_connect(&cli, desthost, &dest_ip)) { + DEBUG(3,("connected to password server %s\n",p)); + break; + } + } + + if (!p) { + DEBUG(1,("password server not available\n")); + cli_shutdown(&cli); + return NULL; + } + + if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { + DEBUG(1,("%s rejected the session\n",desthost)); + cli_shutdown(&cli); + return NULL; + } + + DEBUG(3,("got session\n")); + + if (!cli_negprot(&cli)) { + DEBUG(1,("%s rejected the negprot\n",desthost)); + cli_shutdown(&cli); + return NULL; + } + + if (cli.protocol < PROTOCOL_LANMAN2 || + !(cli.sec_mode & 1)) { + DEBUG(1,("%s isn't in user level security mode\n",desthost)); + cli_shutdown(&cli); + return NULL; + } + + DEBUG(3,("password server OK\n")); + + return &cli; +} + +/**************************************************************************** +validate a password with the password server +****************************************************************************/ +BOOL server_validate(char *user, char *domain, + char *pass, int passlen, + char *ntpass, int ntpasslen) +{ + extern fstring local_machine; + + if (!cli.initialised) { + DEBUG(1,("password server %s is not connected\n", cli.desthost)); + return(False); + } + + if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", cli.desthost)); + return False; + } + + /* if logged in as guest then reject */ + if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); + return(False); + } + + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); + return False; + } + + + if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { + DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); + cli_tdis(&cli); + return False; + } + + if (cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); + cli_tdis(&cli); + return False; + } + + if (!strequal(cli.eff_name, user)) { + DEBUG(1,("password server %s gave different username %s\n", + cli.desthost, + cli.eff_name)); + cli_tdis(&cli); + return False; + } + + DEBUG(3,("password server %s accepted the password\n", cli.desthost)); + + cli_tdis(&cli); + + return(True); +} + + -- cgit From 7097597fd64353f023fae28124bae20e74fd18ed Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 Dec 1997 23:27:40 +0000 Subject: HPUX trusted systems need to use bigcrypt() not crypt() (This used to be commit 979eaf9e9c4dd58f1371597585d4cd64841febd0) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 185fc68f5a..2176d5dafa 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -781,6 +781,10 @@ Hence we make a direct return to avoid a second chance!!! return(linux_bigcrypt(password,this_salt,this_crypted)); #endif +#ifdef HPUX_10_TRUSTED + return(bigcrypt(password,this_salt,this_crypted)); +#endif + #ifdef NO_CRYPT DEBUG(1,("Warning - no crypt available\n")); return(False); -- cgit From 69460b470f44c82b677a41d65ab4e172fc7b284b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 3 Dec 1997 03:43:05 +0000 Subject: allow users to disable the NetWkstaUserLogon call in server level security by changing a setting in local.h or adding it to their Makefile. See comment in local.h (This used to be commit cc10fdf7583ec644850445ad96afd8b22b71e86f) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2176d5dafa..1c72f0cfa6 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1589,6 +1589,7 @@ BOOL server_validate(char *user, char *domain, } +#if USE_NETWKSTAUSERLOGON if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); cli_tdis(&cli); @@ -1608,6 +1609,7 @@ BOOL server_validate(char *user, char *domain, cli_tdis(&cli); return False; } +#endif DEBUG(3,("password server %s accepted the password\n", cli.desthost)); -- cgit From 0e7be4859732283602732ac6a2110712221dc442 Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Sat, 10 Jan 1998 11:42:29 +0000 Subject: Following discussions with Cristian Gafton (Red Hat) we have decided to make PAM silent about it's actions. This reduced error logging for EVERY password validation request. Refer to password.c PAM section for further info. Fiels Affected: password.c (This used to be commit 7a1a8042dd005e26e610a16eaaa693f119b874c7) --- source3/smbd/password.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1c72f0cfa6..c2b916a0af 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -442,13 +442,19 @@ static BOOL pam_auth(char *this_user,char *password) PAM_username = this_user; pam_error = pam_start("samba", this_user, &PAM_conversation, &pamh); PAM_BAIL; - pam_error = pam_authenticate(pamh, 0); +/* Setting PAM_SILENT stops generation of error messages to syslog + * to enable debugging on Red Hat Linux set: + * /etc/pam.d/samba: + * auth required /lib/security/pam_pwdb.so nullok shadow audit + * _OR_ change PAM_SILENT to 0 to force detailed reporting (logging) + */ + pam_error = pam_authenticate(pamh, PAM_SILENT); PAM_BAIL; /* It is not clear to me that account management is the right thing * to do, but it is not clear that it isn't, either. This can be * removed if no account management should be done. Alternately, * put a pam_allow.so entry in /etc/pam.conf for account handling. */ - pam_error = pam_acct_mgmt(pamh, 0); + pam_error = pam_acct_mgmt(pamh, PAM_SILENT); PAM_BAIL; pam_end(pamh, PAM_SUCCESS); /* If this point is reached, the user has been authenticated. */ -- cgit From 55f400bd84f26027f5ec9b7fa06b22895de7557c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 22 Jan 1998 13:27:43 +0000 Subject: This is *not* a big change (although it looks like one). This is merely updating the Copyright statements from 1997 to 1998. It's a once a year thing :-). NO OTHER CHANGES WERE MADE. Jeremy. (This used to be commit b9c16977231efb274e08856f7f3f4408dad6d96c) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c2b916a0af..567b8f54f2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -2,7 +2,7 @@ Unix SMB/Netbios implementation. Version 1.9. Password and authentication handling - Copyright (C) Andrew Tridgell 1992-1997 + Copyright (C) Andrew Tridgell 1992-1998 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- cgit From a215c98602c0849819a50de6b13f8c41824ef08a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Jan 1998 13:52:17 +0000 Subject: Changed code that truncates salt after 2 characters so that it becomes HPUX specific. This fixes a bug with FreeBSD md5 crypt implementation that needs all of the password characters. It seems better to make this an HPUX specific thing. Jeremy. (This used to be commit 91a2b746d3fac261d4be3bd7afa3d5bb601b3d27) --- source3/smbd/password.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 567b8f54f2..0f8705d4be 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1023,7 +1023,10 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) /* extract relevant info */ strcpy(this_user,pass->pw_name); strcpy(this_salt,pass->pw_passwd); +#ifdef HPUX + /* The crypt on HPUX won't work with more than 2 salt characters. */ this_salt[2] = 0; +#endif /* HPUX */ strcpy(this_crypted,pass->pw_passwd); if (!*this_crypted) { -- cgit From 5546e28e69b1a43dbb48e024e233d8ebf7fa667a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 7 Feb 1998 12:15:20 +0000 Subject: A small raft of changes, I will sync up with 1.9.18 also. chgpasswd.c: Fixed typo in debug message. includes.h: Fix include for aix. kanji.c: Added cap_to_sj as inverse of sj_to_cap. loadparm.c: local.h: password.c: Added code for "networkstation user login" parameter. - patch from Rob Nielsen . printing.c: Added further aix printing fixes. reply.c: Changed access time fetch to a function. trans2.c: Changed access time fetch to a function. time.c: Changed access time fetch to a function. server.c: Made NT redirector workaround final. util.c: Added debug for write_socket failing. Jeremy. (This used to be commit a031404623c22d62f8de035be2239f609af08112) --- source3/smbd/password.c | 61 +++++++++++++++++++++++++++++++------------------ 1 file changed, 39 insertions(+), 22 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0f8705d4be..607d01d2cf 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -514,9 +514,14 @@ static BOOL dfs_auth(char *this_user,char *password) * Assumes local passwd file is kept in sync w/ DCE RGY! */ - if (!strcmp((char *)crypt(password,this_salt),this_crypted) || - dcelogin_atmost_once) - return(False); + /* Fix for original (broken) code from Brett Wooldridge */ + if (dce_login_atmost_once) + return (False); + /* This can be ifdefed as the DCE check below is stricter... */ +#ifndef NO_CRYPT + if ( strcmp((char *)crypt(password,this_salt),this_crypted) ) + return (False); +#endif if (sec_login_setup_identity( (unsigned char *)this_user, @@ -1597,28 +1602,40 @@ BOOL server_validate(char *user, char *domain, return False; } + /* + * This patch from Rob Nielsen makes doing + * the NetWksaUserLogon a dynamic, rather than compile-time + * parameter, defaulting to on. This is somewhat dangerous + * as it allows people to turn off this neccessary check, + * but so many people have had problems with this that I + * think it is a neccessary change. JRA. + */ + + if (lp_net_wksta_user_logon()) { + DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli.desthost)); + if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { + DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); + cli_tdis(&cli); + return False; + } -#if USE_NETWKSTAUSERLOGON - if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); - cli_tdis(&cli); - return False; - } - - if (cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); - cli_tdis(&cli); - return False; - } + if (cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); + cli_tdis(&cli); + return False; + } - if (!strequal(cli.eff_name, user)) { - DEBUG(1,("password server %s gave different username %s\n", - cli.desthost, - cli.eff_name)); - cli_tdis(&cli); - return False; + if (!strequal(cli.eff_name, user)) { + DEBUG(1,("password server %s gave different username %s\n", + cli.desthost, + cli.eff_name)); + cli_tdis(&cli); + return False; + } } -#endif + else { + DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli.desthost)); + } DEBUG(3,("password server %s accepted the password\n", cli.desthost)); -- cgit From 45dab9f06594777e96be5f4556e6bb386f68f309 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Feb 1998 22:58:21 +0000 Subject: Makefile, password.c, includes.h: Added KRB4 patches from Johan Hedin nmbd_packets.c: Patch for aliased interfaces from Daniel Haun . Jeremy. (This used to be commit 60f6302b1972e49159bf6e1a838e691268e4399c) --- source3/smbd/password.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 607d01d2cf..1911515404 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -670,6 +670,32 @@ static BOOL krb5_auth(char *this_user,char *password) } #endif /* KRB5_AUTH */ +#ifdef KRB4_AUTH +/******************************************************************* +check on Kerberos authentication +********************************************************************/ +static BOOL krb4_auth(char *this_user,char *password) +{ + char realm[REALM_SZ]; + char tkfile[MAXPATHLEN]; + + if (krb_get_lrealm(realm, 1) != KSUCCESS) + (void) strncpy(realm, KRB_REALM, sizeof (realm)); + + (void) sprintf(tkfile, "/tmp/samba_tkt_%d", getpid()); + + krb_set_tkt_string(tkfile); + if (krb_verify_user(this_user, "", realm, + password, 0, + "rmcd") == KSUCCESS) { + unlink(tkfile); + return 1; + } + unlink(tkfile); + return 0; +} +#endif /* KRB4_AUTH */ + #ifdef LINUX_BIGCRYPT /**************************************************************************** an enhanced crypt for Linux to handle password longer than 8 characters @@ -775,6 +801,10 @@ Hence we make a direct return to avoid a second chance!!! if (krb5_auth(this_user,password)) return(True); #endif +#ifdef KRB4_AUTH + if (krb4_auth(this_user,password)) return(True); +#endif + #ifdef PWDAUTH if (pwdauth(this_user,password) == 0) return(True); -- cgit From 3fb9f9db569e0fe02777e1e7805f20e668309cfe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 4 Mar 1998 01:50:47 +0000 Subject: Adding Korean and Traditional Chinese codepage support. Jeremy. (This used to be commit 2df47cf1bb3428fbaa8dcf45ec114ec3aaafae57) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1911515404..a51e5f639f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -515,7 +515,7 @@ static BOOL dfs_auth(char *this_user,char *password) */ /* Fix for original (broken) code from Brett Wooldridge */ - if (dce_login_atmost_once) + if (dcelogin_atmost_once) return (False); /* This can be ifdefed as the DCE check below is stricter... */ #ifndef NO_CRYPT -- cgit From fdeea341ed1bae670382e45eb731db1b5838ad21 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 11 Mar 1998 21:11:04 +0000 Subject: "For I have laboured mightily on Luke's code, and hath broken all I saw" - the book of Jeremy, chapter 1 :-). So here is the mega-merge of the NTDOM branch server code. It doesn't include the new client side pieces, we'll look at that later. This should give the same functionality, server wise, as the NTDOM branch does, only merged into the main branch. Any fixes to domain controler functionality should be added to the main branch, not the NTDOM branch. This code compiles without warnings on gcc2.8, but will need further testing before we are sure all the working functionality of the NTDOM server branch has been correctly carried over. I hereby declare the server side of the NTDOM branch dead (and all who sail in her :-). Jeremy. (This used to be commit 118ba4d77a33248e762a2cf843fb7cbc906ee6e7) --- source3/smbd/password.c | 103 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 75 insertions(+), 28 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a51e5f639f..b422dda36c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -876,6 +876,68 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha return (memcmp(p24, password, 24) == 0); } +/**************************************************************************** + Do a specific test for an smb password being correct, given a smb_password and + the lanman and NT responses. +****************************************************************************/ + +BOOL smb_password_ok(struct smb_passwd *smb_pass, + uchar lm_pass[24], uchar nt_pass[24]) +{ + uchar challenge[8]; + + if (!lm_pass || !smb_pass) return(False); + + if(smb_pass->acct_ctrl & ACB_DISABLED) + { + DEBUG(3,("smb_password_ok: account for user %s was disabled.\n", smb_pass->smb_name)); + return(False); + } + + if (!last_challenge(challenge)) + { + DEBUG(1,("smb_password_ok: no challenge done - password failed\n")); + return False; + } + + DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n", smb_pass->smb_name)); + + if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) + { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); + if (smb_password_check(nt_pass, smb_pass->smb_nt_passwd, challenge)) + { + DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); + return(True); + } + DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); + } + + /* Try against the lanman password. smb_pass->smb_passwd == NULL means + no password, allow access. */ + + DEBUG(4,("Checking LM MD4 password\n")); + + if((smb_pass->smb_passwd == NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ)) + { + DEBUG(4,("smb_password_ok: no password required for user %s\n", smb_pass->smb_name)); + return True; + } + + if((smb_pass->smb_passwd != NULL) && smb_password_check(lm_pass, smb_pass->smb_passwd, challenge)) + { + DEBUG(4,("smb_password_ok: LM MD4 password check succeeded\n")); + return(True); + } + + DEBUG(4,("smb_password_ok: LM MD4 password check failed\n")); + + return False; +} + /**************************************************************************** check if a username/password is OK ****************************************************************************/ @@ -940,6 +1002,13 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } + /* Quit if the account was disabled. */ + if(smb_pass->acct_ctrl & ACB_DISABLED) + { + DEBUG(3,("password_ok: account for user %s was disabled.\n", user)); + return(False); + } + /* Ensure the uid's match */ if (smb_pass->smb_userid != pass->pw_uid) { @@ -947,35 +1016,13 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - if (Protocol >= PROTOCOL_NT1) - { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - if (smb_pass->smb_nt_passwd != NULL) - { - DEBUG(4,("Checking NT MD4 password\n")); - if (smb_password_check(password, - smb_pass->smb_nt_passwd, - (unsigned char *)challenge)) - { - update_protected_database(user,True); - return(True); - } - DEBUG(4,("NT MD4 password check failed\n")); - } - } - - /* Try against the lanman password */ - - if (smb_password_check(password, - smb_pass->smb_passwd, - (unsigned char *)challenge)) { - update_protected_database(user,True); - return(True); - } + if(smb_password_ok( smb_pass, password, password)) + { + update_protected_database(user,True); + return(True); + } - DEBUG(3,("Error smb_password_check failed\n")); + DEBUG(3,("Error smb_password_check failed\n")); } DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen)); -- cgit From 2e68682069ff72096f341b2fd3079aadf7c70a2f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 12 Mar 1998 02:43:46 +0000 Subject: move setup_groups() into password.c so that swat can link without including server.o (This used to be commit 67bb8835c76e3efc43de55493971fe2402c0d709) --- source3/smbd/password.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b422dda36c..212d931e87 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -147,6 +147,92 @@ char *validated_username(uint16 vuid) return(vuser->name); } + +/**************************************************************************** +Setup the groups a user belongs to. +****************************************************************************/ +int setup_groups(char *user, int uid, int gid, int *p_ngroups, + int **p_igroups, gid_t **p_groups, + int **p_attrs) +{ + if (-1 == initgroups(user,gid)) + { + if (getuid() == 0) + { + DEBUG(0,("Unable to initgroups!\n")); + if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000) + DEBUG(0,("This is probably a problem with the account %s\n",user)); + } + } + else + { + int i,ngroups; + int *igroups; + int *attrs; + gid_t grp = 0; + ngroups = getgroups(0,&grp); + if (ngroups <= 0) + ngroups = 32; + igroups = (int *)malloc(sizeof(int)*ngroups); + attrs = (int *)malloc(sizeof(int)*ngroups); + for (i=0;i 0) + { + /* does getgroups return ints or gid_t ?? */ + static BOOL groups_use_ints = True; + + if (groups_use_ints && + ngroups == 1 && + SVAL(igroups,2) == 0x4242) + groups_use_ints = False; + + for (i=0;groups_use_ints && i Date: Mon, 16 Mar 1998 18:31:09 +0000 Subject: includes.h: Addition of NetBSD 1.3 fix, fix for HPUX 9.x, 10.x zombie problem. password.c: Fix for Thursby to stop Dave clients failing in share mode security (this was their bug - they were interpreting the uid field in share mode which is explicitly denied by the spec but it's easier for us to fix it than them :-). Jeremy. (This used to be commit 39372d9e20803d32c0c5b87226a72b007978baad) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 212d931e87..c0e89100ea 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -243,6 +243,10 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ + /* Ensure no vuid gets registered in share level security. */ + if(lp_security() == SEC_SHARE) + return UID_FIELD_INVALID; + #if 0 /* * After observing MS-Exchange services writing to a Samba share -- cgit From c54af0f8b20e3f93c59da6a817920e1de6c4a870 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 16 Mar 1998 20:59:47 +0000 Subject: Adding the same change as was added to 1.9.18 branch to add the "name resolve order" parameter. source/Makefile: Re-ordered link for name resolve order code. source/clientgen.c: source/clientutil.c: Added calls to resolve_name(). source/includes.h: Added HPUX zombie fix. source/loadparm.c: Added new name resolve order parameter. source/namequery.c: Re-wrote to include parsing of lmhosts file, new resolve_name() function requested by John. source/nmbd.c: Tell resolve_name not to do WINS lookups if we are the WINS server. source/nmbd_lmhosts.c: Call lmhosts parsing functions in namequery.c source/password.c: Call resolve_name() to lookup security=server name. source/reply.c: source/time.c: source/trans2.c: "fake directory create times" fix from Jim Hague - hague@research.canon.com.au. source/util.c: Removed isalnum() test in Get_Hostname() that seems to cause problems on many systems. Jeremy. (This used to be commit 7f118970da7c43eaddcf92dc056d3e849f1e7d5c) --- source3/smbd/password.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c0e89100ea..bb0aacac7e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1689,11 +1689,10 @@ struct cli_state *server_cryptkey(void) standard_sub_basic(desthost); strupper(desthost); - dest_ip = *interpret_addr2(desthost); - if (zero_ip(dest_ip)) { - DEBUG(1,("Can't resolve address for %s\n",p)); - continue; - } + if(!resolve_name( desthost, &dest_ip)) { + DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",p)); + continue; + } if (ismyip(dest_ip)) { DEBUG(1,("Password server loop - disabling password server %s\n",p)); -- cgit From f996885676f041437430bfd5843a3000611b0923 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 17 Mar 1998 12:31:43 +0000 Subject: this isn't a big commit, it just looks like it :-) I needed the client_name() and client_addr() functions in swat so I could tell who was connecting from where. The problem was that these functions didn't take a file descriptor parameter they just used the global "Client". So I needed to change all calls to pass a parameter ... lots of files. (This used to be commit a776058900a727591bd7b69debdaa25c0e31d693) --- source3/smbd/password.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index bb0aacac7e..ffa75d7d0b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1640,21 +1640,21 @@ BOOL check_hosts_equiv(char *user) fname = lp_hosts_equiv(); /* note: don't allow hosts.equiv on root */ - if (fname && *fname && (pass->pw_uid != 0)) - { - if (check_user_equiv(user,client_name(),fname)) - return(True); - } + if (fname && *fname && (pass->pw_uid != 0)) { + extern int Client; + if (check_user_equiv(user,client_name(Client),fname)) + return(True); + } if (lp_use_rhosts()) { char *home = get_home_dir(user); - if (home) - { - sprintf(rhostsfile, "%s/.rhosts", home); - if (check_user_equiv(user,client_name(),rhostsfile)) - return(True); - } + if (home) { + extern int Client; + sprintf(rhostsfile, "%s/.rhosts", home); + if (check_user_equiv(user,client_name(Client),rhostsfile)) + return(True); + } } return(False); -- cgit From d1cc06083dff66519d2a2418d7cce9916131a6da Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Thu, 9 Apr 1998 14:13:20 +0000 Subject: Added const cast to struct args to get rid of compile time warning. (This used to be commit 5d956abb4f4ed22671dfb1c7cb51489ab280463f) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ffa75d7d0b..be032c5c38 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -468,7 +468,7 @@ static char *PAM_password; * echo off means password. */ static int PAM_conv (int num_msg, - struct pam_message **msg, + const struct pam_message **msg, struct pam_response **resp, void *appdata_ptr) { int replies = 0; -- cgit From cac6a060af598bf94e6414b06e7365ec51ca360e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 13 Apr 1998 19:24:06 +0000 Subject: Changes to allow Samba to be compiled with -Wstrict-prototypes with gcc. (Not a big change although it looks like it :-). Jeremy. (This used to be commit cd2613c57261456485fe4eeecfda209ada70de8e) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index be032c5c38..74ebeb1617 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -819,7 +819,7 @@ try all combinations with N uppercase letters. offset is the first char to try and change (start with 0) it assumes the string starts lowercased ****************************************************************************/ -static BOOL string_combinations2(char *s,int offset,BOOL (*fn)(),int N) +static BOOL string_combinations2(char *s,int offset,BOOL (*fn)(char *),int N) { int len = strlen(s); int i; @@ -850,7 +850,7 @@ try all combinations with up to N uppercase letters. offset is the first char to try and change (start with 0) it assumes the string starts lowercased ****************************************************************************/ -static BOOL string_combinations(char *s,BOOL (*fn)(),int N) +static BOOL string_combinations(char *s,BOOL (*fn)(char *),int N) { int n; for (n=1;n<=N;n++) -- cgit From 2a53d6f7077de596265a3e73e79827392054142c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 14 Apr 1998 00:41:59 +0000 Subject: Modified interfaces to getting smb password entries from get_smbpwd_entry (now an internal function to smbpass.c) to a more UNIX-like : getsmbpwnam() - get entry by name. getsmbpwuid() - get entry by uid. Changed the type returned by the smbpasswd enumeration functions to be a void * so that people don't come to depend on it being a FILE *. These abstractions should make it much easier to replace the smbpasswd file with a better backend in future. Other files changed are to match the above changes. Jeremy. (This used to be commit 1161cfb7f2b0d5a6d3e2b524a14a6f325ce70efb) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 74ebeb1617..bbd9f8b849 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1084,8 +1084,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - /* non-null username indicates search by username not smb userid */ - smb_pass = get_smbpwd_entry(user, 0); + smb_pass = getsmbpwnam(user); + if (!smb_pass) { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); -- cgit From efb71742ca8ff9ec3211c5b3cf5d311fdceecd1c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 20 Apr 1998 22:43:54 +0000 Subject: Makefile: Added genrand.o clientgen.c: Changed to fill change password buffer with random stuff. password.c: Changed to get challenge from genrand.c server.c: Added #ifdef around O_SYNC. version.h: Changed to 1.9.19prealpha. genrand.c: New code to generate (hopefully) good random numbers for use in crypto challenges/session keys etc. PLEASE REVIEW THIS CODE AND SUGGEST IMPROVEMENTS !!!!!! Jeremy. (This used to be commit 608e98546392fd0aac9b33f4feac43615dbb4405) --- source3/smbd/password.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index bbd9f8b849..fe3ac5c765 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -45,6 +45,12 @@ Get the next challenge value - no repeats. ********************************************************************/ void generate_next_challenge(char *challenge) { +#if 0 + /* + * Leave this ifdef'd out while we test + * the new crypto random number generator. + * JRA. + */ unsigned char buf[16]; static int counter = 0; struct timeval tval; @@ -59,7 +65,11 @@ void generate_next_challenge(char *challenge) /* mash it up with md4 */ mdfour(buf, (unsigned char *)challenge, 8); +#else + unsigned char buf[8]; + generate_random_buffer(buf,8,False); +#endif memcpy(saved_challenge, buf, 8); memcpy(challenge,buf,8); challenge_sent = True; -- cgit From 2dee1ed38867504d067d593c62734ecff0eca77c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Apr 1998 02:23:24 +0000 Subject: clientgen.c: Added cli_ulogoff() call. password.c: Added call to cli_ulogoff on successfull sessionsetup. Jeremy. (This used to be commit 77882f002b2a8203aad419e485fc885303d999a0) --- source3/smbd/password.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fe3ac5c765..b4d728d0c2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1816,6 +1816,7 @@ BOOL server_validate(char *user, char *domain, DEBUG(3,("password server %s accepted the password\n", cli.desthost)); cli_tdis(&cli); + cli_ulogoff(&cli); return(True); } -- cgit From c41f6c8fdf20ead45658f93ab4d42cb97545f10d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Apr 1998 02:27:12 +0000 Subject: Added cli_ulogoff() calls to all the exit code paths in security=server. Jeremy. (This used to be commit 78d87a5bfdfc6d3f4428591d30294fe7d05d0f91) --- source3/smbd/password.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b4d728d0c2..b69b58f54e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1769,12 +1769,14 @@ BOOL server_validate(char *user, char *domain, /* if logged in as guest then reject */ if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); + cli_ulogoff(&cli); return(False); } if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); + cli_ulogoff(&cli); return False; } @@ -1792,12 +1794,14 @@ BOOL server_validate(char *user, char *domain, if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); cli_tdis(&cli); + cli_ulogoff(&cli); return False; } if (cli.privilages == 0) { DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); cli_tdis(&cli); + cli_ulogoff(&cli); return False; } @@ -1806,6 +1810,7 @@ BOOL server_validate(char *user, char *domain, cli.desthost, cli.eff_name)); cli_tdis(&cli); + cli_ulogoff(&cli); return False; } } -- cgit From 8584c6bd6621eefb49aff69581caf28e38b4ceda Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 22 Apr 1998 00:56:38 +0000 Subject: genrand.c: Improved generation of random values, more secure. loadparm.c: Started add of 'security=domain' code. password.c: Fix for security=server NT bugs. reply.c: Started add of 'security=domain' code. server.c: Started add of 'security=domain' code. smb.h: Started add of 'security=domain' code. Jeremy. (This used to be commit e6bda112ebe0d41f54c4249b5c2e1f24011347e1) --- source3/smbd/password.c | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b69b58f54e..c347f2de0d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1755,12 +1755,48 @@ BOOL server_validate(char *user, char *domain, char *ntpass, int ntpasslen) { extern fstring local_machine; + static unsigned char badpass[24]; if (!cli.initialised) { DEBUG(1,("password server %s is not connected\n", cli.desthost)); return(False); } + if(badpass[0] == 0) { + memset(badpass, 0x1f, sizeof(badpass)); + } + + if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { + /* Very unlikely, our random bad password is the same as the users + password. */ + memset(badpass, badpass[0]+1, sizeof(badpass)); + } + + /* + * Attempt a session setup with a totally incorrect password. + * If this succeeds with the guest bit *NOT* set then the password + * server is broken and is not correctly setting the guest bit. We + * need to detect this as some versions of NT4.x are broken. JRA. + */ + + if (cli_session_setup(&cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass), + domain)) { + if ((SVAL(cli.inbuf,smb_vwv2) & 1) == 0) { + DEBUG(0,("server_validate: password server %s allows users as non-guest \ +with a bad password.\n", cli.desthost)); + DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ +use this machine as the password server.\n")); + cli_ulogoff(&cli); + return False; + } + cli_ulogoff(&cli); + } + + /* + * Now we know the password server will correctly set the guest bit, or is + * not guest enabled, we can try with the real password. + */ + if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { DEBUG(1,("password server %s rejected the password\n", cli.desthost)); return False; @@ -1773,7 +1809,6 @@ BOOL server_validate(char *user, char *domain, return(False); } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); cli_ulogoff(&cli); @@ -1825,5 +1860,3 @@ BOOL server_validate(char *user, char *domain, return(True); } - - -- cgit From a85f5bc268a1c13334b86ac3a44a026359c09371 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 18:54:57 +0000 Subject: genrand.c: Changed SMB_PASSWD_FILE to lp_smb_passwd_file(). password.c: Started the initial code for domain_client_validate(). All bracketed with #ifdef DOMAIN_CLIENT for now. reply.c: Call to domain_client_validate(). All bracketed with #ifdef DOMAIN_CLIENT for now. smbpass.c: New code to get/set machine passwords. Tidied up nesting of lock calls. Jeremy. (This used to be commit 89fe059a6816f32d2cc5c4c04c4089b60590e7e6) --- source3/smbd/password.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c347f2de0d..04a1795e7f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -31,6 +31,8 @@ extern int Protocol; /* users from session setup */ static pstring session_users=""; +extern pstring myname; + /* these are kept here to keep the string_combinations function simple */ static char this_user[100]=""; static char this_salt[100]=""; @@ -1860,3 +1862,74 @@ use this machine as the password server.\n")); return(True); } + +#ifdef DOMAIN_CLIENT +BOOL domain_client_validate( char *user, char *domain, + char *smb_apasswd, int smb_apasslen, + char *smb_ntpasswd, int smb_ntpasslen) +{ + unsigned char local_lm_hash[21]; + unsigned char local_nt_hash[21]; + unsigned char local_challenge[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_reponse[24]; + BOOL encrypted = True; + + /* + * Check that the requested domain is not our own machine name. + * If it is, we should never check the PDC here, we use our own local + * password file. + */ + + if(strequal( domain, myname)) { + DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); + return False; + } + + /* + * Next, check that the passwords given were encrypted. + */ + + if(smb_apasslen != 24 || smb_ntpasslen != 24) { + + /* + * Not encrypted - do so. + */ + + DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); + encrypted = False; + memset(local_lm_hash, '\0', sizeof(local_lm_hash)); + E_P16((uchar *) smb_apasswd, local_lm_hash); + memset(local_nt_hash, '\0', sizeof(local_nt_hash)); + E_md4hash((uchar *) smb_ntpasswd, local_nt_hash); + generate_random_buffer( local_challenge, 8, False); + E_P24(local_lm_hash, local_challenge, local_lm_response); + E_P24(local_nt_hash, local_challenge, local_nt_reponse); + smb_apasslen = 24; + smb_ntpasslen = 24; + smb_apasswd = (char *)local_lm_response; + smb_ntpasswd = (char *)local_nt_reponse; + } else { + + /* + * Encrypted - get the challenge we sent for these + * responses. + */ + + if (!last_challenge(local_challenge)) { + DEBUG(0,("domain_client_validate: no challenge done - password failed\n")); + return False; + } + } + + /* + * At this point, smb_apasswd points to the lanman response to + * the challenge in local_challenge, and smb_ntpasswd points to + * the NT response to the challenge in local_challenge. Ship + * these over the secure channel to a domain controller and + * see if they were valid. + */ + + return False; +} +#endif /* DOMAIN_CLIENT */ -- cgit From 002a47de8e0cf03c79cedbed2db52f391001f459 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 20:12:17 +0000 Subject: clientgen.c: Added rap error codes to cli_error, moved from smbpasswd.c password.c: Changed global cli -> pw_cli, removed strtok (bad strtok, bad :-) use in security=server, started to extend security=domain code. smbpasswd.c: Removed rap error code functions. Jeremy. (This used to be commit 0f00b8fce1a5cad7f8c212568fa33f09986e5bd6) --- source3/smbd/password.c | 215 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 161 insertions(+), 54 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 04a1795e7f..d627edf1cd 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1673,14 +1673,14 @@ BOOL check_hosts_equiv(char *user) } -static struct cli_state cli; +static struct cli_state pw_cli; /**************************************************************************** return the client state structure ****************************************************************************/ struct cli_state *server_client(void) { - return &cli; + return &pw_cli; } /**************************************************************************** @@ -1692,61 +1692,63 @@ struct cli_state *server_cryptkey(void) struct in_addr dest_ip; extern fstring local_machine; char *p; + BOOL connected_ok = False; - if (!cli_initialise(&cli)) + if (!cli_initialise(&pw_cli)) return NULL; - - for (p=strtok(lp_passwordserver(),LIST_SEP); p ; p = strtok(NULL,LIST_SEP)) { - fstrcpy(desthost,p); + + p = lp_passwordserver(); + while(p && next_token( &p, desthost, LIST_SEP)) { standard_sub_basic(desthost); strupper(desthost); if(!resolve_name( desthost, &dest_ip)) { - DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",p)); + DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); continue; } if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",p)); + DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); continue; } - if (cli_connect(&cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",p)); + if (cli_connect(&pw_cli, desthost, &dest_ip)) { + DEBUG(3,("connected to password server %s\n",desthost)); + connected_ok = True; break; } } - if (!p) { - DEBUG(1,("password server not available\n")); - cli_shutdown(&cli); + if (!connected_ok) { + DEBUG(0,("password server not available\n")); + cli_shutdown(&pw_cli); return NULL; } - if (!cli_session_request(&cli, desthost, 0x20, local_machine)) { + if (!cli_session_request(&pw_cli, desthost, 0x20, local_machine)) { DEBUG(1,("%s rejected the session\n",desthost)); - cli_shutdown(&cli); + cli_shutdown(&pw_cli); return NULL; } DEBUG(3,("got session\n")); - if (!cli_negprot(&cli)) { + if (!cli_negprot(&pw_cli)) { DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(&cli); + cli_shutdown(&pw_cli); return NULL; } - if (cli.protocol < PROTOCOL_LANMAN2 || - !(cli.sec_mode & 1)) { + if (pw_cli.protocol < PROTOCOL_LANMAN2 || + !(pw_cli.sec_mode & 1)) { DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(&cli); + cli_shutdown(&pw_cli); return NULL; } DEBUG(3,("password server OK\n")); - return &cli; + return &pw_cli; } /**************************************************************************** @@ -1759,8 +1761,8 @@ BOOL server_validate(char *user, char *domain, extern fstring local_machine; static unsigned char badpass[24]; - if (!cli.initialised) { - DEBUG(1,("password server %s is not connected\n", cli.desthost)); + if (!pw_cli.initialised) { + DEBUG(1,("password server %s is not connected\n", pw_cli.desthost)); return(False); } @@ -1781,17 +1783,17 @@ BOOL server_validate(char *user, char *domain, * need to detect this as some versions of NT4.x are broken. JRA. */ - if (cli_session_setup(&cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass), + if (cli_session_setup(&pw_cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass), domain)) { - if ((SVAL(cli.inbuf,smb_vwv2) & 1) == 0) { + if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) == 0) { DEBUG(0,("server_validate: password server %s allows users as non-guest \ -with a bad password.\n", cli.desthost)); +with a bad password.\n", pw_cli.desthost)); DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - cli_ulogoff(&cli); + cli_ulogoff(&pw_cli); return False; } - cli_ulogoff(&cli); + cli_ulogoff(&pw_cli); } /* @@ -1799,21 +1801,21 @@ use this machine as the password server.\n")); * not guest enabled, we can try with the real password. */ - if (!cli_session_setup(&cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli.desthost)); + if (!cli_session_setup(&pw_cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", pw_cli.desthost)); return False; } /* if logged in as guest then reject */ - if ((SVAL(cli.inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli.desthost)); - cli_ulogoff(&cli); + if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", pw_cli.desthost)); + cli_ulogoff(&pw_cli); return(False); } - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); - cli_ulogoff(&cli); + if (!cli_send_tconX(&pw_cli, "IPC$", "IPC", "", 1)) { + DEBUG(1,("password server %s refused IPC$ connect\n", pw_cli.desthost)); + cli_ulogoff(&pw_cli); return False; } @@ -1827,43 +1829,48 @@ use this machine as the password server.\n")); */ if (lp_net_wksta_user_logon()) { - DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli.desthost)); - if (!cli_NetWkstaUserLogon(&cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", cli.desthost)); - cli_tdis(&cli); - cli_ulogoff(&cli); + DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); + if (!cli_NetWkstaUserLogon(&pw_cli,user,local_machine)) { + DEBUG(1,("password server %s failed NetWkstaUserLogon\n", pw_cli.desthost)); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return False; } - if (cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", cli.desthost)); - cli_tdis(&cli); - cli_ulogoff(&cli); + if (pw_cli.privilages == 0) { + DEBUG(1,("password server %s gave guest privilages\n", pw_cli.desthost)); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return False; } - if (!strequal(cli.eff_name, user)) { + if (!strequal(pw_cli.eff_name, user)) { DEBUG(1,("password server %s gave different username %s\n", - cli.desthost, - cli.eff_name)); - cli_tdis(&cli); - cli_ulogoff(&cli); + pw_cli.desthost, + pw_cli.eff_name)); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return False; } } else { - DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli.desthost)); + DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); } - DEBUG(3,("password server %s accepted the password\n", cli.desthost)); + DEBUG(3,("password server %s accepted the password\n", pw_cli.desthost)); - cli_tdis(&cli); - cli_ulogoff(&cli); + cli_tdis(&pw_cli); + cli_ulogoff(&pw_cli); return(True); } #ifdef DOMAIN_CLIENT +/*********************************************************************** + Do the same as security=server, but using NT Domain calls and a session + key from the machine password. +************************************************************************/ + BOOL domain_client_validate( char *user, char *domain, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) @@ -1874,6 +1881,11 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; BOOL encrypted = True; + fstring remote_machine; + char *p; + struct in_addr dest_ip; + struct cli_state cli; + BOOL connected_ok = False; /* * Check that the requested domain is not our own machine name. @@ -1930,6 +1942,101 @@ BOOL domain_client_validate( char *user, char *domain, * see if they were valid. */ + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + p = lp_passwordserver(); + while(p && next_token( &p, remote_machine, LIST_SEP)) { + + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if(!resolve_name( remote_machine, &dest_ip)) { + DEBUG(1,("domain_client_validate: Can't resolve address for %s\n", remote_machine)); + continue; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("domain_client_validate: Password server loop - not using password server %s\n",remote_machine)); + continue; + } + + memset(&cli, '\0', sizeof(struct cli_state)); + + if (!cli_connect(&cli, remote_machine, &dest_ip)) { + DEBUG(0,("domain_client_validate: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + continue; + } + + if (!cli_session_request(&cli, remote_machine, 0x20, myname)) { + DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + cli.protocol = PROTOCOL_NT1; + + if (!cli_negprot(&cli)) { + DEBUG(0,("domain_client_validate: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + if (cli.protocol != PROTOCOL_NT1) { + DEBUG(0,("domain_client_validate: machine %s didn't negotiate NT protocol.\n", + remote_machine)); + cli_shutdown(&cli); + continue; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { + DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + if (!(cli.sec_mode & 1)) { + DEBUG(1,("domain_client_validate: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(&cli); + continue; + } + + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("domain_client_validate: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(&cli) )); + cli_shutdown(&cli); + continue; + } + + /* + * We have an anonymous connection to IPC$. + */ + connected_ok = True; + break; + } + + if (!connected_ok) { + DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + cli_shutdown(&cli); + return False; + } + + /* + * Ok - we have an anonymous connection to the IPC$ share. + * Now start the NT Domain stuff :-). + */ + return False; } #endif /* DOMAIN_CLIENT */ -- cgit From 30675f81f60bab24f47758baab8316d4467709ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 23 Apr 1998 22:59:19 +0000 Subject: Makefile: Added nterr.c into the mix. clientgen.c: Added nt_error as an entry in the struct client_state. password.c: Open the netlogon pipe. smb.h: Added nt_error as an entry in the struct client_state. lib/rpc/parse/parse_net.c: Added comments on net logon. lib/rpc/server/srv_netlog.c: Added comments on net logon. Jeremy. (This used to be commit 899a9f0dce50c73e03c8da2ebe920957491c8ad7) --- source3/smbd/password.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index d627edf1cd..11ffe4afd1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1886,6 +1886,7 @@ BOOL domain_client_validate( char *user, char *domain, struct in_addr dest_ip; struct cli_state cli; BOOL connected_ok = False; + int fnum; /* * Check that the requested domain is not our own machine name. @@ -2037,6 +2038,18 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); * Now start the NT Domain stuff :-). */ + /* + * First, open the pipe to \PIPE\NETLOGON. + */ + + if((fnum = cli_open(&cli, PIPE_NETLOGON, O_CREAT, DENY_NONE)) == -1) { + DEBUG(0,("domain_client_validate: cli_open on %s on machine %s failed. Error was :%s.\n", + PIPE_NETLOGON, remote_machine, cli_errstr(&cli))); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + return False; } #endif /* DOMAIN_CLIENT */ -- cgit From e7ac86607c80912e55ac7179b100cea22749c16f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 25 Apr 1998 01:12:08 +0000 Subject: This looks like a big change but really isn't. It is changing the global variables "myname" and "myworkgroup" to "global_myname" and "global_myworkgroup" respectively. This is to make it very explicit when we are messing with a global (don't ask - it makes the domain client code much clearer :-). Jeremy. (This used to be commit 866406bfe399cf757c8275093dacd5ce4843afa0) --- source3/smbd/password.c | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 11ffe4afd1..0e9ec620b1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -31,7 +31,7 @@ extern int Protocol; /* users from session setup */ static pstring session_users=""; -extern pstring myname; +extern pstring global_myname; /* these are kept here to keep the string_combinations function simple */ static char this_user[100]=""; @@ -1783,8 +1783,8 @@ BOOL server_validate(char *user, char *domain, * need to detect this as some versions of NT4.x are broken. JRA. */ - if (cli_session_setup(&pw_cli, user, badpass, sizeof(badpass), badpass, sizeof(badpass), - domain)) { + if (cli_session_setup(&pw_cli, user, (char *)badpass, sizeof(badpass), + (char *)badpass, sizeof(badpass), domain)) { if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) == 0) { DEBUG(0,("server_validate: password server %s allows users as non-guest \ with a bad password.\n", pw_cli.desthost)); @@ -1886,7 +1886,6 @@ BOOL domain_client_validate( char *user, char *domain, struct in_addr dest_ip; struct cli_state cli; BOOL connected_ok = False; - int fnum; /* * Check that the requested domain is not our own machine name. @@ -1894,7 +1893,7 @@ BOOL domain_client_validate( char *user, char *domain, * password file. */ - if(strequal( domain, myname)) { + if(strequal( domain, global_myname)) { DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); return False; } @@ -1972,7 +1971,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); continue; } - if (!cli_session_request(&cli, remote_machine, 0x20, myname)) { + if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) { DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); cli_shutdown(&cli); @@ -2033,23 +2032,23 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); return False; } +#if 0 /* for now... JRA */ /* * Ok - we have an anonymous connection to the IPC$ share. * Now start the NT Domain stuff :-). */ - /* - * First, open the pipe to \PIPE\NETLOGON. - */ - - if((fnum = cli_open(&cli, PIPE_NETLOGON, O_CREAT, DENY_NONE)) == -1) { - DEBUG(0,("domain_client_validate: cli_open on %s on machine %s failed. Error was :%s.\n", - PIPE_NETLOGON, remote_machine, cli_errstr(&cli))); + if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) { + DEBUG(0,("domain_client_validate: unable to open the domain client session to \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); + cli_close(&cli, fnum); cli_ulogoff(&cli); cli_shutdown(&cli); - return False; + return False; } + if(cli_nt_setup_creds(&cli,) HERE +#endif return False; } #endif /* DOMAIN_CLIENT */ -- cgit From d3832506b2583130c4f4ba4b3edeabca987b7cbb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 00:02:57 +0000 Subject: This is the checkin that adds the security=domain functionality. WARNING - so far this has only been tested against a Samba PDC (still waiting for IS to add me the machine accounts :-). Still missing is the code in smbpasswd that will add a machine account password and change it on the domain controller, but this is not hard, and I will check it in soon. Jeremy. (This used to be commit 17b94a7084621b3f0106dd4d3386f05cdfc56d19) --- source3/smbd/password.c | 97 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 78 insertions(+), 19 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0e9ec620b1..21424592f1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -32,6 +32,7 @@ extern int Protocol; static pstring session_users=""; extern pstring global_myname; +extern fstring global_myworkgroup; /* these are kept here to keep the string_combinations function simple */ static char this_user[100]=""; @@ -1865,7 +1866,6 @@ use this machine as the password server.\n")); return(True); } -#ifdef DOMAIN_CLIENT /*********************************************************************** Do the same as security=server, but using NT Domain calls and a session key from the machine password. @@ -1875,17 +1875,20 @@ BOOL domain_client_validate( char *user, char *domain, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) { - unsigned char local_lm_hash[21]; - unsigned char local_nt_hash[21]; unsigned char local_challenge[8]; unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; - BOOL encrypted = True; + unsigned char machine_passwd[16]; + time_t lct; fstring remote_machine; char *p; struct in_addr dest_ip; + NET_ID_INFO_CTR ctr; + NET_USER_INFO_3 info3; struct cli_state cli; + uint32 smb_uid_low; BOOL connected_ok = False; + void *vp; /* * Check that the requested domain is not our own machine name. @@ -1909,14 +1912,9 @@ BOOL domain_client_validate( char *user, char *domain, */ DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); - encrypted = False; - memset(local_lm_hash, '\0', sizeof(local_lm_hash)); - E_P16((uchar *) smb_apasswd, local_lm_hash); - memset(local_nt_hash, '\0', sizeof(local_nt_hash)); - E_md4hash((uchar *) smb_ntpasswd, local_nt_hash); generate_random_buffer( local_challenge, 8, False); - E_P24(local_lm_hash, local_challenge, local_lm_response); - E_P24(local_nt_hash, local_challenge, local_nt_reponse); + SMBencrypt( smb_apasswd, local_challenge, local_lm_response); + SMBNTencrypt( smb_ntpasswd, local_challenge, local_nt_reponse); smb_apasslen = 24; smb_ntpasslen = 24; smb_apasswd = (char *)local_lm_response; @@ -1934,6 +1932,29 @@ BOOL domain_client_validate( char *user, char *domain, } } + /* + * Get the machine account password. + */ + if((vp = machine_password_lock( global_myworkgroup, global_myname, False)) == NULL) { + DEBUG(0,("domain_client_validate: unable to open the machine account password file for \ +machine %s in domain %s.\n", global_myname, global_myworkgroup )); + return False; + } + + if(get_machine_account_password( vp, machine_passwd, &lct) == False) { + DEBUG(0,("domain_client_validate: unable to read the machine account password for \ +machine %s in domain %s.\n", global_myname, global_myworkgroup )); + machine_password_unlock(vp); + return False; + } + + machine_password_unlock(vp); + + /* + * Here we should check the last change time to see if the machine + * password needs changing..... TODO... JRA. + */ + /* * At this point, smb_apasswd points to the lanman response to * the challenge in local_challenge, and smb_ntpasswd points to @@ -1942,6 +1963,12 @@ BOOL domain_client_validate( char *user, char *domain, * see if they were valid. */ + memset(&cli, '\0', sizeof(struct cli_state)); + if(cli_initialise(&cli) == False) { + DEBUG(0,("domain_client_validate: unable to initialize client connection.\n")); + return False; + } + /* * Treat each name in the 'password server =' line as a potential * PDC/BDC. Contact each in turn and try and authenticate. @@ -1963,8 +1990,6 @@ BOOL domain_client_validate( char *user, char *domain, continue; } - memset(&cli, '\0', sizeof(struct cli_state)); - if (!cli_connect(&cli, remote_machine, &dest_ip)) { DEBUG(0,("domain_client_validate: unable to connect to SMB server on \ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); @@ -2032,7 +2057,6 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); return False; } -#if 0 /* for now... JRA */ /* * Ok - we have an anonymous connection to the IPC$ share. * Now start the NT Domain stuff :-). @@ -2041,14 +2065,49 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) { DEBUG(0,("domain_client_validate: unable to open the domain client session to \ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); - cli_close(&cli, fnum); + cli_close(&cli, cli.nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); return False; } - if(cli_nt_setup_creds(&cli,) HERE -#endif - return False; + if(cli_nt_setup_creds(&cli, machine_passwd) == False) { + DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ +%s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); + cli_close(&cli, cli.nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + /* We really don't care what LUID we give the user. */ + generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); + + if(cli_nt_login_network(&cli, domain, user, smb_uid_low, local_challenge, + smb_apasswd, smb_ntpasswd, &ctr, &info3) == False) { + DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); + cli_close(&cli, cli.nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + /* + * Here, if we really want it, we have lots of info about the user in info3. + */ + + if(cli_nt_logoff(&cli, &ctr) == False) { + DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); + cli_close(&cli, cli.nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } + + cli_close(&cli, cli.nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return True; } -#endif /* DOMAIN_CLIENT */ -- cgit From a8e7f804ca86c4ae91d6d4429f9fe264947b54f9 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 29 Apr 1998 11:00:12 +0000 Subject: password.c: added become_root / unbecome_root around the get machine account password. smbpass.c: cleaning up code. - turning if (BOOL_expr == False) into if (BOOL_expr) what if you test if (BOOL_expr == True) and someone defines True to be -1 on one system and 1 on another? or if you get inconsistent return results between developers - removed if ((FILE*) == 0) and made this if ((FILE*) == NULL) - cannot assume that NULL is zero integer. plus there are typecast issues to deal with - removed return (ret == 0) ? True : False and made this return ret == 0 rely on the compiler to return correct BOOL value: not all developers will return True or False #defines: stick with BOOL test (non-zero). - removed if (ret == False) replaced with if (!ret) - bug where instead of if (sizeof(pstring)-len-len-6 < 0) it had a boolean test if (pstring-len-len-6). - removed "." after debugging of filenames: the "." - a fullstop - looked like it was part of the filename, making things difficult to sort out. still to be resolved: the global_myname isn't set up, such that the machine account password file is named "TEST3..mac". (This used to be commit 315e26c23abf7137684bf084c825ad241076132e) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 21424592f1..f2ab29001e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1932,6 +1932,8 @@ BOOL domain_client_validate( char *user, char *domain, } } + become_root(False); + /* * Get the machine account password. */ @@ -1950,6 +1952,8 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); machine_password_unlock(vp); + unbecome_root(False); + /* * Here we should check the last change time to see if the machine * password needs changing..... TODO... JRA. -- cgit From e305c2c9e2e657974d34d1d58a8f9372921fdae2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Apr 1998 19:22:01 +0000 Subject: clientgen.c: Fixed null session setup bug. password.c: Stopped cli_nt_logout call (we don't have it correct yet). Added Luke object-orientation fix :-). smb.h: Added clnt_name_slash to cli_state. lib/rpc/client/cli_login.c: Changed global_myname to clnt_name_slash where needed. lib/rpc/client/cli_netlogon.c: Fixed debug messages, don't check creds on error. lib/rpc/client/cli_pipe.c: Fixed debug messages, Added Luke object-orientation fix. lib/rpc/parse/parse_misc.c: Fixed STRING2 linearization bug that was adding 1. Jeremy. (This used to be commit c6c22df20196cb7f0ae84b1a1dd202a87adb8d4e) --- source3/smbd/password.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f2ab29001e..180c51f4ea 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -2069,7 +2069,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) { DEBUG(0,("domain_client_validate: unable to open the domain client session to \ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); - cli_close(&cli, cli.nt_pipe_fnum); + cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); return False; @@ -2078,7 +2078,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); if(cli_nt_setup_creds(&cli, machine_passwd) == False) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); - cli_close(&cli, cli.nt_pipe_fnum); + cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); return False; @@ -2091,7 +2091,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); smb_apasswd, smb_ntpasswd, &ctr, &info3) == False) { DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); - cli_close(&cli, cli.nt_pipe_fnum); + cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); return False; @@ -2101,16 +2101,24 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); * Here, if we really want it, we have lots of info about the user in info3. */ +#if 0 + /* + * We don't actually need to do this - plus it fails currently with + * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to + * send here. JRA. + */ + if(cli_nt_logoff(&cli, &ctr) == False) { DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); - cli_close(&cli, cli.nt_pipe_fnum); + cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); return False; } +#endif /* 0 */ - cli_close(&cli, cli.nt_pipe_fnum); + cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); return True; -- cgit From 3eae1e3f8e53c51f638b1b381085f29feea1c517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 30 Apr 1998 01:39:22 +0000 Subject: Added patch from Bruce Tenison to allow encrypted passwords to be stored over time, allowing a smbpasswd file migration. Adds new parameter "update encrypted". Will also add to 1.9.18 branch. Docs update to follow. Jeremy. (This used to be commit 5d3e874d780d595415cc27a7f5945fc2e694c3ac) --- source3/smbd/password.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 180c51f4ea..57e7775b71 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -423,6 +423,31 @@ static char *osf1_bigcrypt(char *password,char *salt1) } #endif +/**************************************************************************** +update the encrypted smbpasswd file from the plaintext username and password +*****************************************************************************/ +BOOL update_smbpassword_file( char *user, fstring password) +{ + struct smb_passwd *smbpw; + BOOL ret; + + become_root(0); + smbpw = getsmbpwnam(user); + unbecome_root(0); + + if(smbpw == NULL) + { + DEBUG(0,("update_smbpassword_file: getsmbpwnam returned NULL\n")); + return False; + } + + /* Here, the flag is one, because we want to ignore the XXXXXXX'd out password */ + ret = change_oem_password( smbpw, password, True); + if (ret == False) + DEBUG(3,("update_smbpasswd_file: change_oem_password returned False\n")); + + return ret; +} /**************************************************************************** update the enhanced security database. Only relevant for OSF1 at the moment. @@ -1051,6 +1076,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) struct passwd *pass; char challenge[8]; struct smb_passwd *smb_pass; + BOOL update_encrypted = lp_update_encrypted(); BOOL challenge_done = False; if (password) password[pwlen] = 0; @@ -1231,6 +1257,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) if (password_check(password)) { update_protected_database(user,True); + if (update_encrypted) + update_smbpassword_file(user,password); return(True); } @@ -1248,6 +1276,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) if (password_check(password)) { update_protected_database(user,True); + if (update_encrypted) + update_smbpassword_file(user,password); return(True); } @@ -1268,6 +1298,8 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) if (string_combinations(password,password_check,level)) { update_protected_database(user,True); + if (update_encrypted) + update_smbpassword_file(user,password); return(True); } -- cgit From 19f76f391b97b405879fd8574e711a6d59e4e60c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 5 May 1998 19:24:32 +0000 Subject: genrand.c: SGI compile warning fix. ipc.c: Fix for duplicate printer names being long. loadparm.c: Set bNetWkstaUserLogon to false by default - new code in password.c protects us. nmbd_logonnames.c: nmbd_namequery.c: nmbd_namerelease.c: Debug messages fix. password.c: SGI compile warning fix, fix for tcon() with bNetWkstaUserLogon call. reply.c: SGI compile warning fix. server.c Debug messages fix. smbpass.c: Fix for incorrect pointer. Jeremy. (This used to be commit 567d3f838988cafab4770fce1cf68b73085e6c71) --- source3/smbd/password.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 57e7775b71..5127539466 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -91,7 +91,7 @@ BOOL set_challenge(char *challenge) /******************************************************************* get the last challenge sent ********************************************************************/ -BOOL last_challenge(char *challenge) +BOOL last_challenge(unsigned char *challenge) { if (!challenge_sent) return(False); memcpy(challenge,saved_challenge,8); @@ -1036,7 +1036,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check(nt_pass, smb_pass->smb_nt_passwd, challenge)) + if (smb_password_check(nt_pass, (uchar *)smb_pass->smb_nt_passwd, challenge)) { DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); return(True); @@ -1055,7 +1055,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, return True; } - if((smb_pass->smb_passwd != NULL) && smb_password_check(lm_pass, smb_pass->smb_passwd, challenge)) + if((smb_pass->smb_passwd != NULL) && smb_password_check(lm_pass, (uchar *)smb_pass->smb_passwd, challenge)) { DEBUG(4,("smb_password_ok: LM MD4 password check succeeded\n")); return(True); @@ -1074,7 +1074,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) pstring pass2; int level = lp_passwordlevel(); struct passwd *pass; - char challenge[8]; + uchar challenge[8]; struct smb_passwd *smb_pass; BOOL update_encrypted = lp_update_encrypted(); BOOL challenge_done = False; @@ -1846,12 +1846,6 @@ use this machine as the password server.\n")); return(False); } - if (!cli_send_tconX(&pw_cli, "IPC$", "IPC", "", 1)) { - DEBUG(1,("password server %s refused IPC$ connect\n", pw_cli.desthost)); - cli_ulogoff(&pw_cli); - return False; - } - /* * This patch from Rob Nielsen makes doing * the NetWksaUserLogon a dynamic, rather than compile-time @@ -1863,28 +1857,36 @@ use this machine as the password server.\n")); if (lp_net_wksta_user_logon()) { DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); + + if (!cli_send_tconX(&pw_cli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("password server %s refused IPC$ connect\n", pw_cli.desthost)); + cli_ulogoff(&pw_cli); + return False; + } + if (!cli_NetWkstaUserLogon(&pw_cli,user,local_machine)) { - DEBUG(1,("password server %s failed NetWkstaUserLogon\n", pw_cli.desthost)); + DEBUG(0,("password server %s failed NetWkstaUserLogon\n", pw_cli.desthost)); cli_tdis(&pw_cli); cli_ulogoff(&pw_cli); return False; } if (pw_cli.privilages == 0) { - DEBUG(1,("password server %s gave guest privilages\n", pw_cli.desthost)); + DEBUG(0,("password server %s gave guest privilages\n", pw_cli.desthost)); cli_tdis(&pw_cli); cli_ulogoff(&pw_cli); return False; } if (!strequal(pw_cli.eff_name, user)) { - DEBUG(1,("password server %s gave different username %s\n", + DEBUG(0,("password server %s gave different username %s\n", pw_cli.desthost, pw_cli.eff_name)); cli_tdis(&pw_cli); cli_ulogoff(&pw_cli); return False; } + cli_tdis(&pw_cli); } else { DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); @@ -1892,7 +1894,6 @@ use this machine as the password server.\n")); DEBUG(3,("password server %s accepted the password\n", pw_cli.desthost)); - cli_tdis(&pw_cli); cli_ulogoff(&pw_cli); return(True); -- cgit From a2bddb20ed078c3e1b9cb60a7420b3d107898f52 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 May 1998 01:34:51 +0000 Subject: Fixes for the %U and %G problems people have reported. Essentially, multiple session_setup_and_X's may be done to an smbd. As there is only one global variable containing the requested connection name (sessionsetup_user), then any subsequent sessionsetups overwrite this name (causing %U and %G to get the wrong name). This is particularly common when an NT client does a null session setup to get a browse list after the user has connected, but before a share has been mounted. These changes store the requested_name in the vuid structure (so this only really works for user level and above security) and copies this name back into the global variable before the standard_sub call. Jeremy. (This used to be commit b5187ad6a3b3af9fbbeee8bced0ab16b41e9825b) --- source3/smbd/password.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 5127539466..53ed8c85f1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -251,7 +251,7 @@ register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(int uid,int gid, char *name,BOOL guest) +uint16 register_vuid(int uid,int gid, char *unix_name, char *requested_name, BOOL guest) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -298,7 +298,8 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) vuser->uid = uid; vuser->gid = gid; vuser->guest = guest; - strcpy(vuser->name,name); + fstrcpy(vuser->name,unix_name); + fstrcpy(vuser->requested_name,requested_name); vuser->n_sids = 0; vuser->sids = NULL; @@ -310,13 +311,13 @@ uint16 register_vuid(int uid,int gid, char *name,BOOL guest) /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(name,uid,gid, + setup_groups(unix_name,uid,gid, &vuser->n_groups, &vuser->igroups, &vuser->groups, &vuser->attrs); - DEBUG(3,("uid %d registered to name %s\n",uid,name)); + DEBUG(3,("uid %d registered to name %s\n",uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->real_name, "\0"); -- cgit From 346abceb277e3354214599cc3c0f9bac6d44dfc8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 May 1998 18:45:57 +0000 Subject: smbpass.c: Fixed machine_passwd_lock() problems. password.c: Fixed machine_passwd_lock() problems. lib/rpc/server/srv_ldap_helpers.c: Oops - broke proto.h with dummy function. Fixed now. Jeremy. (This used to be commit d28427f21fff49da6b38c24625e3e2dae49a9713) --- source3/smbd/password.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 53ed8c85f1..1056269490 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1922,7 +1922,6 @@ BOOL domain_client_validate( char *user, char *domain, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; - void *vp; /* * Check that the requested domain is not our own machine name. @@ -1971,20 +1970,20 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password. */ - if((vp = machine_password_lock( global_myworkgroup, global_myname, False)) == NULL) { + if(!machine_password_lock( global_myworkgroup, global_myname, False)) { DEBUG(0,("domain_client_validate: unable to open the machine account password file for \ machine %s in domain %s.\n", global_myname, global_myworkgroup )); return False; } - if(get_machine_account_password( vp, machine_passwd, &lct) == False) { + if(get_machine_account_password( machine_passwd, &lct) == False) { DEBUG(0,("domain_client_validate: unable to read the machine account password for \ machine %s in domain %s.\n", global_myname, global_myworkgroup )); - machine_password_unlock(vp); + machine_password_unlock(); return False; } - machine_password_unlock(vp); + machine_password_unlock(); unbecome_root(False); -- cgit From d8d9f7723337c267a8740750fe19a6387cfbb1f6 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 7 May 1998 18:19:05 +0000 Subject: created "passdb.c" which is an interface point to (at present) either smbpasswd or ldap passwd, at compile-time (-DUSE_LDAP). _none_ of the functions in ldap.c or smbpass.c should be called directly: only those in passdb.c should be used. -DUSE_LDAP is unlikely to compile at the moment. (This used to be commit 57b01ad4ffb14ebd600d4e66602b54ed987f6106) --- source3/smbd/password.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1056269490..82e3a024e1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -429,21 +429,21 @@ update the encrypted smbpasswd file from the plaintext username and password *****************************************************************************/ BOOL update_smbpassword_file( char *user, fstring password) { - struct smb_passwd *smbpw; + struct smb_passwd *sampw; BOOL ret; become_root(0); - smbpw = getsmbpwnam(user); + sampw = getsampwnam(user); unbecome_root(0); - if(smbpw == NULL) + if(sampw == NULL) { - DEBUG(0,("update_smbpassword_file: getsmbpwnam returned NULL\n")); + DEBUG(0,("update_smbpassword_file: getsampwnam returned NULL\n")); return False; } /* Here, the flag is one, because we want to ignore the XXXXXXX'd out password */ - ret = change_oem_password( smbpw, password, True); + ret = change_oem_password( sampw, password, True); if (ret == False) DEBUG(3,("update_smbpasswd_file: change_oem_password returned False\n")); @@ -1124,7 +1124,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - smb_pass = getsmbpwnam(user); + smb_pass = getsampwnam(user); if (!smb_pass) { -- cgit From 839e47c5a62fb42d3e0b2e083ad23243e9cec566 Mon Sep 17 00:00:00 2001 From: John Terpstra Date: Sun, 10 May 1998 06:20:27 +0000 Subject: Updated OSF1_ENH_SEC mode password handling. This now tries Enhanced passwords first and if this fails trys Basic mode (ie: Unix /etc/passwd) authentication. This only happens when OSF1_ENH_SEC is defined at compilation. (This used to be commit 29462c8d7a241eb462b1583170a0b5f16096ea3f) --- source3/smbd/password.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 82e3a024e1..8dfae21ad1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -940,7 +940,14 @@ Hence we make a direct return to avoid a second chance!!! #endif #ifdef OSF1_ENH_SEC - return(strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); + { + BOOL ret = (strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); + if(!ret) { + DEBUG(2,("password_check: OSF1_ENH_SEC failed. Trying normal crypt.\n")); + ret = (strcmp((char *)crypt(password,this_salt),this_crypted) == 0); + } + return ret; + } #endif #ifdef ULTRIX_AUTH -- cgit From 3dfc0c847240ac7e12c39f4ed9c31a888949ade1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 11 May 1998 06:38:36 +0000 Subject: changed to use slprintf() instead of sprintf() just about everywhere. I've implemented slprintf() as a bounds checked sprintf() using mprotect() and a non-writeable page. This should prevent any sprintf based security holes. (This used to be commit ee09e9dadb69aaba5a751dd20ccc6d587d841bd6) --- source3/smbd/password.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8dfae21ad1..67de0523e8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1044,7 +1044,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check(nt_pass, (uchar *)smb_pass->smb_nt_passwd, challenge)) + if (smb_password_check((char *)nt_pass, (uchar *)smb_pass->smb_nt_passwd, challenge)) { DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); return(True); @@ -1063,7 +1063,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, return True; } - if((smb_pass->smb_passwd != NULL) && smb_password_check(lm_pass, (uchar *)smb_pass->smb_passwd, challenge)) + if((smb_pass->smb_passwd != NULL) && smb_password_check((char *)lm_pass, (uchar *)smb_pass->smb_passwd, challenge)) { DEBUG(4,("smb_password_ok: LM MD4 password check succeeded\n")); return(True); @@ -1153,7 +1153,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - if(smb_password_ok( smb_pass, password, password)) + if(smb_password_ok( smb_pass, (unsigned char *)password,(uchar *)password)) { update_protected_database(user,True); return(True); @@ -1704,7 +1704,7 @@ BOOL check_hosts_equiv(char *user) char *home = get_home_dir(user); if (home) { extern int Client; - sprintf(rhostsfile, "%s/.rhosts", home); + slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); if (check_user_equiv(user,client_name(Client),rhostsfile)) return(True); } @@ -1953,8 +1953,8 @@ BOOL domain_client_validate( char *user, char *domain, DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); generate_random_buffer( local_challenge, 8, False); - SMBencrypt( smb_apasswd, local_challenge, local_lm_response); - SMBNTencrypt( smb_ntpasswd, local_challenge, local_nt_reponse); + SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); + SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse); smb_apasslen = 24; smb_ntpasslen = 24; smb_apasswd = (char *)local_lm_response; @@ -2127,7 +2127,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); /* We really don't care what LUID we give the user. */ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - if(cli_nt_login_network(&cli, domain, user, smb_uid_low, local_challenge, + if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge, smb_apasswd, smb_ntpasswd, &ctr, &info3) == False) { DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); -- cgit From f004d84f683673b7cb167320e3e78a3fcefdfd07 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 11 May 1998 15:56:01 +0000 Subject: ldap back-end database development Makefile: created PASSBD_OBJ group includes.h: added #ifdef USE_LDAP to #include headers ldap.c: - renamed "_machine" to "_trust" everywhere. - added sam_passwd support routines - removed get_ldappwd_entry function: replaced with get_sampwd_entry - removed getldappwnam/uid: replaced with getsampwnam/uid - other messing about bits which are probably going to annoy the hell out of jean-francois (sorry!) mkproto.awk: - added stuff to wrap ldap.c protos with #ifdef USE_LDAP - added uid_t and gid_t return results to the prototype generation passdb.c: - created getsam21pwent, add_sam21pwd_entry, mod_sam21pwd_entry. - modified getsampwnam/uid and created getsam21pwnam/rid functions to replace the local get_smbpwd_entry() and get_ldappwd_entry() functions, which jeremy didn't like anyway because they were dual-purpose. - added utility routines which are or may be useful to all the password database routines. password.c: - renamed "machine_" to "trust_" everywhere. smbpass.c: - removed get_smbpwd_entry function: replaced it with get_sampwd_entry functions in passdb.c - moved code that decoded acct_ctrl into passdb.c - moved encode_acct_ctrl into passdb.c - removed getsmbpwnam/uid: replaced with getsampwnam/uid - renamed "machine_" to "trust_" everywhere. smbpasswd.c: - renamed "machine_" to "trust_" everywhere. util.c: - moved gethexpwd function into passdb.c lib/rpc/server/srv_util.c: - moved user_rid_to_uid, group_rid_to_rid etc etc into passdb.c (This used to be commit 673ab50c4c2c25db355d90efde3a6bfbb4d8369e) --- source3/smbd/password.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 67de0523e8..327bfba371 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1919,7 +1919,7 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_challenge[8]; unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; - unsigned char machine_passwd[16]; + unsigned char trust_passwd[16]; time_t lct; fstring remote_machine; char *p; @@ -1977,20 +1977,20 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password. */ - if(!machine_password_lock( global_myworkgroup, global_myname, False)) { + if(!trust_password_lock( global_myworkgroup, global_myname, False)) { DEBUG(0,("domain_client_validate: unable to open the machine account password file for \ machine %s in domain %s.\n", global_myname, global_myworkgroup )); return False; } - if(get_machine_account_password( machine_passwd, &lct) == False) { + if(get_trust_account_password( trust_passwd, &lct) == False) { DEBUG(0,("domain_client_validate: unable to read the machine account password for \ machine %s in domain %s.\n", global_myname, global_myworkgroup )); - machine_password_unlock(); + trust_password_unlock(); return False; } - machine_password_unlock(); + trust_password_unlock(); unbecome_root(False); @@ -2115,7 +2115,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); return False; } - if(cli_nt_setup_creds(&cli, machine_passwd) == False) { + if(cli_nt_setup_creds(&cli, trust_passwd) == False) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); cli_nt_session_close(&cli); -- cgit From f888868f46a5418bac9ab528497136c152895305 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 May 1998 00:55:32 +0000 Subject: This is a security audit change of the main source. It removed all ocurrences of the following functions : sprintf strcpy strcat The replacements are slprintf, safe_strcpy and safe_strcat. It should not be possible to use code in Samba that uses sprintf, strcpy or strcat, only the safe_equivalents. Once Andrew has fixed the slprintf implementation then this code will be moved back to the 1.9.18 code stream. Jeremy. (This used to be commit 2d774454005f0b54e5684cf618da7060594dfcbb) --- source3/smbd/password.c | 50 ++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 327bfba371..3040775e03 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -349,8 +349,8 @@ void add_session_user(char *user) DEBUG(1,("Too many session users??\n")); else { - strcat(session_users," "); - strcat(session_users,suser); + pstrcat(session_users," "); + pstrcat(session_users,suser); } } } @@ -364,7 +364,7 @@ static struct spwd *getspnam(char *username) /* fake shadow password routine */ { FILE *f; char line[1024]; - static char pw[20]; + static fstring pw; static struct spwd static_spwd; static_spwd.sp_pwdp=0; @@ -380,7 +380,7 @@ static struct spwd *getspnam(char *username) /* fake shadow password routine */ *q=0; if (q-p+1>20) break; - strcpy(pw, p); + fstrcpy(pw, p); static_spwd.sp_pwdp=pw; } break; @@ -415,7 +415,7 @@ static char *osf1_bigcrypt(char *password,char *salt1) for (i=0; ipw_name,mypasswd->ufld.fd_name); - strcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt); + fstrcpy(pass->pw_name,mypasswd->ufld.fd_name); + fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt); } else { @@ -1233,20 +1233,20 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) AUTHORIZATION *ap = getauthuid( pass->pw_uid ); if (ap) { - strcpy( pass->pw_passwd, ap->a_password ); + fstrcpy( pass->pw_passwd, ap->a_password ); endauthent(); } } #endif /* extract relevant info */ - strcpy(this_user,pass->pw_name); - strcpy(this_salt,pass->pw_passwd); + fstrcpy(this_user,pass->pw_name); + fstrcpy(this_salt,pass->pw_passwd); #ifdef HPUX /* The crypt on HPUX won't work with more than 2 salt characters. */ this_salt[2] = 0; #endif /* HPUX */ - strcpy(this_crypted,pass->pw_passwd); + fstrcpy(this_crypted,pass->pw_passwd); if (!*this_crypted) { if (!lp_null_passwords()) { @@ -1295,7 +1295,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) update_protected_database(user,False); /* restore it */ - strcpy(password,pass2); + fstrcpy(password,pass2); return(False); } @@ -1314,7 +1314,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) update_protected_database(user,False); /* restore it */ - strcpy(password,pass2); + fstrcpy(password,pass2); return(False); } @@ -1384,7 +1384,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (member && *member) { static fstring name; - strcpy(name,*member); + fstrcpy(name,*member); if (user_ok(name,snum) && password_ok(name,password,pwlen,NULL)) return(&name[0]); @@ -1400,7 +1400,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) { /* This Entry have PASSWORD and same GID then check pwd */ if (password_ok(NULL, password, pwlen, pwd)) { - strcpy(tm, pwd->pw_name); + fstrcpy(tm, pwd->pw_name); endpwent (); return tm; } @@ -1460,7 +1460,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->name,snum) && password_ok(vuser->name, password, pwlen, NULL)) { - strcpy(user, vuser->name); + fstrcpy(user, vuser->name); vuser->guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); ok = True; @@ -1480,12 +1480,12 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, auser = strtok(NULL,LIST_SEP)) { fstring user2; - strcpy(user2,auser); + fstrcpy(user2,auser); if (!user_ok(user2,snum)) continue; if (password_ok(user2,password, pwlen, NULL)) { ok = True; - strcpy(user,user2); + fstrcpy(user,user2); DEBUG(3,("ACCEPTED: session list username and given password ok\n")); } } @@ -1496,7 +1496,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!ok && !lp_revalidate(snum) && (vuser != 0) && !vuser->guest && user_ok(vuser->name,snum)) { - strcpy(user,vuser->name); + fstrcpy(user,vuser->name); *guest = False; DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); ok = True; @@ -1526,19 +1526,19 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (auser) { ok = True; - strcpy(user,auser); + fstrcpy(user,auser); DEBUG(3,("ACCEPTED: group username and given password ok\n")); } } else { fstring user2; - strcpy(user2,auser); + fstrcpy(user2,auser); if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL)) { ok = True; - strcpy(user,user2); + fstrcpy(user,user2); DEBUG(3,("ACCEPTED: user list username and given password ok\n")); } } @@ -1553,7 +1553,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); if (Get_Pwnam(guestname,True)) { - strcpy(user,guestname); + fstrcpy(user,guestname); ok = True; DEBUG(3,("ACCEPTED: guest account and guest ok\n")); } -- cgit From ffab54750f0eec202895670dd9293ee4aa3eb475 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 18 May 1998 21:30:57 +0000 Subject: chgpasswd.c: Changed back to getsmb... from getsam... ldap.c: Stoped dummy_function being prototyped. loadparm.c: Fixed slprintf sizes. nisppass.c: Fixed safe_strcpy sizes. nmbd_processlogon.c: Changed back to getsmb... from getsam... nttrans.c: Just a dump of new code. passdb.c: Moved stuff around a lot - stopped any lookups by rid. This needs to be indirected through a function table (soon). password.c: Changed back to getsmb... from getsam... reply.c: Changed back to getsmb... from getsam... slprintf.c: Fixed prototype problems. smb.h: Fixed prototype problems. smbpass.c: Changed to getsmbfile.... smbpasswd.c: Changed back to getsmb... from getsam... lib/rpc/server/srv_netlog.c: Changed back to getsmb... from getsam... lib/rpc/server/srv_samr.c: Fixed rid lookup - use uid or gid lookup. lib/rpc/server/srv_util.c: Changed back to getsmb... from getsam... Jeremy. (This used to be commit 7d332b2493d2089d09521250fc9b72d8953307c0) --- source3/smbd/password.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3040775e03..a8d9ece557 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -429,21 +429,21 @@ update the encrypted smbpasswd file from the plaintext username and password *****************************************************************************/ BOOL update_smbpassword_file( char *user, fstring password) { - struct smb_passwd *sampw; + struct smb_passwd *smbpw; BOOL ret; become_root(0); - sampw = getsampwnam(user); + smbpw = getsmbpwnam(user); unbecome_root(0); - if(sampw == NULL) + if(smbpw == NULL) { - DEBUG(0,("update_smbpassword_file: getsampwnam returned NULL\n")); + DEBUG(0,("update_smbpassword_file: getsmbpwnam returned NULL\n")); return False; } /* Here, the flag is one, because we want to ignore the XXXXXXX'd out password */ - ret = change_oem_password( sampw, password, True); + ret = change_oem_password( smbpw, password, True); if (ret == False) DEBUG(3,("update_smbpasswd_file: change_oem_password returned False\n")); @@ -1131,7 +1131,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } - smb_pass = getsampwnam(user); + smb_pass = getsmbpwnam(user); if (!smb_pass) { -- cgit From bfa013908f2b0e3c8c9bed4c6f5c6ec9ee0931cc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 21 May 1998 23:59:04 +0000 Subject: Fixed 'revalidate' parameter so it's only considered in security=share mode. Jeremy. (This used to be commit 7727f09ea9055053ed1d3e2af1069ddae245efb4) --- source3/smbd/password.c | 58 ++++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 29 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a8d9ece557..0f2efcc1da 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1469,38 +1469,38 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* now check the list of session users */ - if (!ok) - { - char *auser; - char *user_list = strdup(session_users); - if (!user_list) return(False); + if (!ok) + { + char *auser; + char *user_list = strdup(session_users); + if (!user_list) return(False); - for (auser=strtok(user_list,LIST_SEP); - !ok && auser; - auser = strtok(NULL,LIST_SEP)) - { - fstring user2; - fstrcpy(user2,auser); - if (!user_ok(user2,snum)) continue; + for (auser=strtok(user_list,LIST_SEP); + !ok && auser; + auser = strtok(NULL,LIST_SEP)) + { + fstring user2; + fstrcpy(user2,auser); + if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen, NULL)) { - ok = True; - fstrcpy(user,user2); - DEBUG(3,("ACCEPTED: session list username and given password ok\n")); - } - } - free(user_list); - } - - /* check for a previously validated username/password pair */ - if (!ok && !lp_revalidate(snum) && - (vuser != 0) && !vuser->guest && - user_ok(vuser->name,snum)) { - fstrcpy(user,vuser->name); - *guest = False; - DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); - ok = True; + if (password_ok(user2,password, pwlen, NULL)) { + ok = True; + fstrcpy(user,user2); + DEBUG(3,("ACCEPTED: session list username and given password ok\n")); + } } + free(user_list); + } + + /* check for a previously validated username/password pair */ + if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) && + (vuser != 0) && !vuser->guest && + user_ok(vuser->name,snum)) { + fstrcpy(user,vuser->name); + *guest = False; + DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); + ok = True; + } /* check for a rhosts entry */ if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { -- cgit From 9bd7e1e8870da87ea6f3c9e78933beeb08b65a0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 27 May 1998 00:30:52 +0000 Subject: loadparm.c: Added machine password timeout parameter - set to 7 days be default. password.c: Added code to tell server.c when machine password needs changing. server.c: Change machine password in idle cycles if it needs it. smbpassfile.c: Fixed up length calculations for machine password file. smbpasswd.c: Moved domain joining code/machine password changing code. lib/rpc/client/cli_netlogon.c: And this is where it now lives. Jeremy. (This used to be commit b8fedca6191de96159df0d1d17082d82e8e44773) --- source3/smbd/password.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0f2efcc1da..48fd7cbe24 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -28,6 +28,8 @@ extern int DEBUGLEVEL; extern int Protocol; +BOOL global_machine_pasword_needs_changing; + /* users from session setup */ static pstring session_users=""; @@ -1972,8 +1974,6 @@ BOOL domain_client_validate( char *user, char *domain, } } - become_root(False); - /* * Get the machine account password. */ @@ -1992,13 +1992,14 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); trust_password_unlock(); - unbecome_root(False); - /* * Here we should check the last change time to see if the machine * password needs changing..... TODO... JRA. */ + if(time(NULL) > lct + lp_machine_password_timeout()) + global_machine_pasword_needs_changing = True; + /* * At this point, smb_apasswd points to the lanman response to * the challenge in local_challenge, and smb_ntpasswd points to -- cgit From 5b5eb35c91ec400a25f6e6cf3eec421bd9560d50 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 13 Jun 1998 03:04:00 +0000 Subject: Makefile: Added ubi_sLinkList.o as the groupname.o file needs it. Added groupname.o includes.h: Added ubi_sLinkList.h include. loadparm.c: Added groupname map parameter. password.c: Fix HPUX big_crypt. username.c: New user_in_list() code. Moved groupname map code to groupname.c lib/rpc/server/srv_util.c: Added lookup_wellknown_sid_from_name(). New groupname map stuff. Note that nothing currently uses this but at compiles ok. Jeremy. (This used to be commit beef636a4d772457816ef068c62ea965d07131f6) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 48fd7cbe24..277e3a592e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -961,7 +961,7 @@ Hence we make a direct return to avoid a second chance!!! #endif #ifdef HPUX_10_TRUSTED - return(bigcrypt(password,this_salt,this_crypted)); + return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0); #endif #ifdef NO_CRYPT -- cgit From 7a2b695bcbf80f192eea8db09a3f30c2cf75412d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 6 Jul 1998 22:48:21 +0000 Subject: password.c: Fixes to allow Win95 clients to have lm encrypted passwords recognised. lib/rpc/client/cli_login.c: Fix debug comment. lib/rpc/parse/parse_misc.c: Fix for passing null pointers. lib/rpc/parse/parse_net.c: Send correct password lengths when called from Win95. Jeremy. (This used to be commit ad1848b35521b3d478ea3226db818a1edef78254) --- source3/smbd/password.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 277e3a592e..1924a32780 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1947,7 +1947,8 @@ BOOL domain_client_validate( char *user, char *domain, * Next, check that the passwords given were encrypted. */ - if(smb_apasslen != 24 || smb_ntpasslen != 24) { + if(((smb_apasslen != 24) && (smb_apasslen != 0)) || + ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) { /* * Not encrypted - do so. @@ -2129,7 +2130,9 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge, - smb_apasswd, smb_ntpasswd, &ctr, &info3) == False) { + ((smb_apasslen != 0) ? smb_apasswd : NULL), + ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), + &ctr, &info3) == False) { DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); cli_nt_session_close(&cli); -- cgit From 86de50535f66c8ad51374b19fedb0377060ac8ba Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 9 Jul 1998 19:13:01 +0000 Subject: New version of the DFS_AUTH code from Karsten Muuss Jeremy. (This used to be commit cf7402c5325afd1f9a737facf285cb905702adb2) --- source3/smbd/password.c | 281 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 242 insertions(+), 39 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1924a32780..e160580e5f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -623,6 +623,19 @@ static BOOL afs_auth(char *this_user,char *password) #ifdef DFS_AUTH +/***************************************************************** + This new version of the DFS_AUTH code was donated by Karsten Muuss + . It fixes the following problems with the + old code : + + - Server credentials may expire + - Client credential cache files have wrong owner + - purge_context() function is called with invalid argument + + This new code was modified to ensure that on exit the uid/gid is + still root, and the original directory is restored. JRA. +******************************************************************/ + sec_login_handle_t my_dce_sec_context; int dcelogin_atmost_once = 0; @@ -634,70 +647,261 @@ static BOOL dfs_auth(char *this_user,char *password) error_status_t err; int err2; int prterr; + signed32 expire_time, current_time; boolean32 password_reset; - sec_passwd_rec_t my_dce_password; + struct passwd *pw; + sec_passwd_rec_t passwd_rec; sec_login_auth_src_t auth_src = sec_login_auth_src_network; unsigned char dce_errstr[dce_c_error_string_len]; + if (dcelogin_atmost_once) return(False); + +#ifndef NO_CRYPT /* * We only go for a DCE login context if the given password * matches that stored in the local password file.. * Assumes local passwd file is kept in sync w/ DCE RGY! */ - /* Fix for original (broken) code from Brett Wooldridge */ - if (dcelogin_atmost_once) - return (False); - /* This can be ifdefed as the DCE check below is stricter... */ -#ifndef NO_CRYPT if ( strcmp((char *)crypt(password,this_salt),this_crypted) ) - return (False); + return(False); #endif - if (sec_login_setup_identity( - (unsigned char *)this_user, - sec_login_no_flags, - &my_dce_sec_context, - &err) == 0) + sec_login_get_current_context(&my_dce_sec_context, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get current context. %s\n", dce_errstr)); + + return(False); + } + + sec_login_certify_identity(my_dce_sec_context, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get current context. %s\n", dce_errstr)); + + return(False); + } + + sec_login_get_expiration(my_dce_sec_context, &expire_time, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr)); + + return(False); + } + + time(¤t_time); + + if (expire_time < (current_time + 60)) { + struct passwd *pw; + sec_passwd_rec_t *key; + + sec_login_get_pwent(my_dce_sec_context, + (sec_login_passwd_t*)&pw, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); + + return(False); + } + + sec_login_refresh_identity(my_dce_sec_context, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't refresh identity. %s\n", dce_errstr)); + + return(False); + } + + sec_key_mgmt_get_key(rpc_c_authn_dce_secret, NULL, + (unsigned char *)pw->pw_name, + sec_c_key_version_none, + (void**)&key, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get key for %s. %s\n", pw->pw_name, dce_errstr)); + + return(False); + } + + sec_login_valid_and_cert_ident(my_dce_sec_context, key, + &password_reset, &auth_src, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't validate and certify identity for %s. %s\n", + pw->pw_name, dce_errstr)); + } + + sec_key_mgmt_free_key(key, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't free key.\n", dce_errstr)); + } + } + + if (sec_login_setup_identity((unsigned char *)this_user, + sec_login_no_flags, + &my_dce_sec_context, + &err) == 0) + { dce_error_inq_text(err, dce_errstr, &err2); DEBUG(0,("DCE Setup Identity for %s failed: %s\n", - this_user,dce_errstr)); + this_user,dce_errstr)); return(False); } - my_dce_password.version_number = sec_passwd_c_version_none; - my_dce_password.pepper = NULL; - my_dce_password.key.key_type = sec_passwd_plain; - my_dce_password.key.tagged_union.plain = (idl_char *)password; - - if (sec_login_valid_and_cert_ident(my_dce_sec_context, - &my_dce_password, - &password_reset, - &auth_src, - &err) == 0 ) - { + sec_login_get_pwent(my_dce_sec_context, + (sec_login_passwd_t*)&pw, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); + + return(False); + } + + sec_login_purge_context(&my_dce_sec_context, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't purge context. %s\n", dce_errstr)); + + return(False); + } + + /* + * NB. I'd like to change these to call something like become_user() + * instead but currently we don't have a connection + * context to become the correct user. This is already + * fairly platform specific code however, so I think + * this should be ok. I have added code to go + * back to being root on error though. JRA. + */ + + if (setregid(-1, pw->pw_gid) != 0) { + DEBUG(0,("Can't set egid to %d (%s)\n", pw->pw_gid, strerror(errno))); + return False; + } + + if (setreuid(-1, pw->pw_uid) != 0) { + setgid(0); + DEBUG(0,("Can't set euid to %d (%s)\n", pw->pw_uid, strerror(errno))); + return False; + } + + if (sec_login_setup_identity((unsigned char *)this_user, + sec_login_no_flags, + &my_dce_sec_context, + &err) == 0) + + { dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n", - this_user,dce_errstr)); - + /* Go back to root, JRA. */ + setuid(0); + setgid(0); + DEBUG(0,("DCE Setup Identity for %s failed: %s\n", + this_user,dce_errstr)); return(False); } + sec_login_get_pwent(my_dce_sec_context, + (sec_login_passwd_t*)&pw, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + /* Go back to root, JRA. */ + setuid(0); + setgid(0); + DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); + + return(False); + } + + passwd_rec.version_number = sec_passwd_c_version_none; + passwd_rec.pepper = NULL; + passwd_rec.key.key_type = sec_passwd_plain; + passwd_rec.key.tagged_union.plain = (idl_char *)password; + + sec_login_validate_identity(my_dce_sec_context, + &passwd_rec, &password_reset, + &auth_src, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + /* Go back to root, JRA. */ + setuid(0); + setgid(0); + DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n", + this_user,dce_errstr)); + + return(False); + } + + sec_login_certify_identity(my_dce_sec_context, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + /* Go back to root, JRA. */ + setuid(0); + setgid(0); + DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr)); + + return(False); + } + + if (auth_src != sec_login_auth_src_network) { + DEBUG(0,("DCE context has no network credentials.\n")); + } + sec_login_set_context(my_dce_sec_context, &err); - if (err != error_status_ok ) - { + if (err != error_status_ok ) { dce_error_inq_text(err, dce_errstr, &err2); DEBUG(0,("DCE login failed for principal %s, cant set context: %s\n", - this_user,dce_errstr)); - sec_login_purge_context(my_dce_sec_context, &err); + this_user,dce_errstr)); + + sec_login_purge_context(&my_dce_sec_context, &err); + /* Go back to root, JRA. */ + setuid(0); + setgid(0); return(False); } - else - { - DEBUG(0,("DCE login succeeded for principal %s on pid %d\n", - this_user, getpid())); - } + + sec_login_get_pwent(my_dce_sec_context, + (sec_login_passwd_t*)&pw, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); + + /* Go back to root, JRA. */ + setuid(0); + setgid(0); + return(False); + } + + DEBUG(0,("DCE login succeeded for principal %s on pid %d\n", + this_user, getpid())); + + DEBUG(3,("DCE principal: %s\n" + " uid: %d\n" + " gid: %d\n", + pw->pw_name, pw->pw_uid, pw->pw_gid)); + DEBUG(3,(" info: %s\n" + " dir: %s\n" + " shell: %s\n", + pw->pw_gecos, pw->pw_dir, pw->pw_shell)); + + sec_login_get_expiration(my_dce_sec_context, &expire_time, &err); + if (err != error_status_ok ) { + dce_error_inq_text(err, dce_errstr, &err2); + /* Go back to root, JRA. */ + setuid(0); + setgid(0); + DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr)); + + return(False); + } + + setuid(0); + setgid(0); + + DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time)))); dcelogin_atmost_once = 1; return (True); @@ -709,15 +913,14 @@ void dfs_unlogin(void) int err2; unsigned char dce_errstr[dce_c_error_string_len]; - sec_login_purge_context(my_dce_sec_context, &err); + sec_login_purge_context(&my_dce_sec_context, &err); if (err != error_status_ok ) { dce_error_inq_text(err, dce_errstr, &err2); DEBUG(0,("DCE purge login context failed for server instance %d: %s\n", - getpid(), dce_errstr)); + getpid(), dce_errstr)); } } - #endif #ifdef KRB5_AUTH -- cgit From 1aa138922e5c0e4925ff5cbfcdb4e7cad367b31b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 27 Jul 1998 18:50:45 +0000 Subject: chgpasswd.c: Fixed up debug calls to stop crashes if ptsname failed. local.h: Kept FSTYPE_STRING as Samba for now. nmbd_browsesync.c: Added bugfix from Matt Chapman mattyc@cyberdude.com - lmb_browserlist is now a struct ubi_dlList not a struct browse_cache_record *. server.c: smb.h: uid.c: password.c: Removed attrs code - it is not used anywhere. Jeremy (This used to be commit ef1af7fe6d5c58ae57b8e4efff0729e1a315da43) --- source3/smbd/password.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e160580e5f..711729f86d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -134,17 +134,15 @@ void invalidate_vuid(uint16 vuid) vuser->n_sids = 0; - /* same number of igroups as groups as attrs */ + /* same number of igroups as groups */ vuser->n_groups = 0; if (vuser->groups && (vuser->groups != (gid_t *)vuser->igroups)) free(vuser->groups); if (vuser->igroups) free(vuser->igroups); - if (vuser->attrs ) free(vuser->attrs); if (vuser->sids ) free(vuser->sids); - vuser->attrs = NULL; vuser->sids = NULL; vuser->igroups = NULL; vuser->groups = NULL; @@ -167,8 +165,7 @@ char *validated_username(uint16 vuid) Setup the groups a user belongs to. ****************************************************************************/ int setup_groups(char *user, int uid, int gid, int *p_ngroups, - int **p_igroups, gid_t **p_groups, - int **p_attrs) + int **p_igroups, gid_t **p_groups) { if (-1 == initgroups(user,gid)) { @@ -183,25 +180,19 @@ int setup_groups(char *user, int uid, int gid, int *p_ngroups, { int i,ngroups; int *igroups; - int *attrs; gid_t grp = 0; ngroups = getgroups(0,&grp); if (ngroups <= 0) ngroups = 32; igroups = (int *)malloc(sizeof(int)*ngroups); - attrs = (int *)malloc(sizeof(int)*ngroups); for (i=0;in_groups = 0; vuser->groups = NULL; vuser->igroups = NULL; - vuser->attrs = NULL; /* Find all the groups this uid is in and store them. Used by become_user() */ setup_groups(unix_name,uid,gid, &vuser->n_groups, &vuser->igroups, - &vuser->groups, - &vuser->attrs); + &vuser->groups); DEBUG(3,("uid %d registered to name %s\n",uid,unix_name)); -- cgit From 64578c0589a3a741f81fb55c16eeb882128da00b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 03:08:05 +0000 Subject: merge from the autoconf2 branch to the main branch (This used to be commit 3bda7ac417107a7b01d91805ca71c4330657ed21) --- source3/smbd/password.c | 107 ++++++++++++------------------------------------ 1 file changed, 27 insertions(+), 80 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 711729f86d..aae398dbda 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,7 @@ #include "includes.h" -#if (defined(NETGROUP) && defined (AUTOMOUNT)) +#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) #include "rpcsvc/ypclnt.h" #endif @@ -347,44 +347,6 @@ void add_session_user(char *user) } -#ifdef NO_GETSPNAM -/* a fake shadow password routine which just fills a fake spwd struct - * with the sp_pwdp field. (sreiz@aie.nl) - */ -static struct spwd *getspnam(char *username) /* fake shadow password routine */ -{ - FILE *f; - char line[1024]; - static fstring pw; - static struct spwd static_spwd; - - static_spwd.sp_pwdp=0; - if (!(f=fopen("/etc/master.passwd", "r"))) - return 0; - while (fgets(line, 1024, f)) { - if (!strncmp(line, username, strlen(username)) && - line[strlen(username)]==':') { /* found entry */ - char *p, *q; - - p=line+strlen(username)+1; - if ((q=strchr(p, ':'))) { - *q=0; - if (q-p+1>20) - break; - fstrcpy(pw, p); - static_spwd.sp_pwdp=pw; - } - break; - } - } - fclose(f); - if (static_spwd.sp_pwdp) - return &static_spwd; - return 0; -} -#endif - - #ifdef OSF1_ENH_SEC /**************************************************************************** an enhanced crypt for OSF1 @@ -480,7 +442,7 @@ static void update_protected_database( char *user, BOOL result) } -#ifdef USE_PAM +#ifdef HAVE_PAM /******************************************************************* check on PAM authentication ********************************************************************/ @@ -583,7 +545,7 @@ static BOOL pam_auth(char *this_user,char *password) #endif -#ifdef AFS_AUTH +#ifdef WITH_AFS /******************************************************************* check on AFS authentication ********************************************************************/ @@ -610,7 +572,7 @@ static BOOL afs_auth(char *this_user,char *password) #endif -#ifdef DFS_AUTH +#ifdef WITH_DFS /***************************************************************** This new version of the DFS_AUTH code was donated by Karsten Muuss @@ -645,7 +607,7 @@ static BOOL dfs_auth(char *this_user,char *password) if (dcelogin_atmost_once) return(False); -#ifndef NO_CRYPT +#ifdef HAVE_CRYPT /* * We only go for a DCE login context if the given password * matches that stored in the local password file.. @@ -1099,24 +1061,24 @@ core of password checking routine BOOL password_check(char *password) { -#ifdef USE_PAM +#ifdef HAVE_PAM /* This falls through if the password check fails - - if NO_CRYPT is defined this causes an error msg + - if HAVE_CRYPT is not defined this causes an error msg saying Warning - no crypt available - - if NO_CRYPT is NOT defined this is a potential security hole + - if HAVE_CRYPT is defined this is a potential security hole as it may authenticate via the crypt call when PAM settings say it should fail. - if (pam_auth(this_user,password)) return(True); -Hence we make a direct return to avoid a second chance!!! + if (pam_auth(this_user,password)) return(True); + Hence we make a direct return to avoid a second chance!!! */ return (pam_auth(this_user,password)); #endif -#ifdef AFS_AUTH +#ifdef WITH_AFS if (afs_auth(this_user,password)) return(True); #endif -#ifdef DFS_AUTH +#ifdef WITH_DFS if (dfs_auth(this_user,password)) return(True); #endif @@ -1128,11 +1090,6 @@ Hence we make a direct return to avoid a second chance!!! if (krb4_auth(this_user,password)) return(True); #endif -#ifdef PWDAUTH - if (pwdauth(this_user,password) == 0) - return(True); -#endif - #ifdef OSF1_ENH_SEC { BOOL ret = (strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); @@ -1152,11 +1109,11 @@ Hence we make a direct return to avoid a second chance!!! return(linux_bigcrypt(password,this_salt,this_crypted)); #endif -#ifdef HPUX_10_TRUSTED +#ifdef HAVE_BIGCRYPT return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0); #endif -#ifdef NO_CRYPT +#ifndef HAVE_CRYPT DEBUG(1,("Warning - no crypt available\n")); return(False); #else @@ -1364,7 +1321,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) return(False); } -#ifdef SHADOW_PWD +#ifdef HAVE_GETSPNAM { struct spwd *spass; @@ -1388,15 +1345,7 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) } #endif -#ifdef SecureWare - { - struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); - if (pr_pw && pr_pw->ufld.fd_encrypt) - pass->pw_passwd = pr_pw->ufld.fd_encrypt; - } -#endif - -#ifdef HPUX_10_TRUSTED +#ifdef HAVE_GETPRPWNAM { struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); if (pr_pw && pr_pw->ufld.fd_encrypt) @@ -1436,23 +1385,21 @@ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) /* extract relevant info */ fstrcpy(this_user,pass->pw_name); fstrcpy(this_salt,pass->pw_passwd); -#ifdef HPUX - /* The crypt on HPUX won't work with more than 2 salt characters. */ + /* crypt on some platforms (HPUX in particular) + won't work with more than 2 salt characters. */ this_salt[2] = 0; -#endif /* HPUX */ + fstrcpy(this_crypted,pass->pw_passwd); if (!*this_crypted) { if (!lp_null_passwords()) { - DEBUG(2,("Disallowing access to %s due to null password\n",this_user)); - return(False); + DEBUG(2,("Disallowing access to %s due to null password\n",this_user)); + return(False); } -#ifndef PWDAUTH if (!*password) { - DEBUG(3,("Allowing access to %s with null password\n",this_user)); - return(True); + DEBUG(3,("Allowing access to %s with null password\n",this_user)); + return(True); } -#endif } /* try it as it came to us */ @@ -1551,7 +1498,7 @@ validate a group username entry. Return the username or NULL ****************************************************************************/ static char *validate_group(char *group,char *password,int pwlen,int snum) { -#ifdef NETGROUP +#ifdef HAVE_NETGROUP { char *host, *user, *domain; setnetgrent(group); @@ -1568,7 +1515,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) } #endif -#if HAVE_GETGRNAM +#ifdef HAVE_GETGRNAM { struct group *gptr = (struct group *)getgrnam(group); char **member; @@ -1824,7 +1771,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { BOOL host_ok = False; -#ifdef NETGROUP +#ifdef HAVE_NETGROUP if (is_group) { static char *mydomain = NULL; @@ -1836,7 +1783,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) #else if (is_group) { - DEBUG(1,("Netgroups not configured - add -DNETGROUP and recompile\n")); + DEBUG(1,("Netgroups not configured\n")); continue; } #endif -- cgit From fb08c34cf3950f994701a9c98c89670f6346f7ab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 29 Jul 1998 05:05:36 +0000 Subject: get rid of the runtime test for broken getgroups() and add a compile time test instead. This also allows us to get rid of the igroups element of a couple of structures. (This used to be commit 8b25fe734166b76ceebf8d9543c706ebe0fddc96) --- source3/smbd/password.c | 108 +++++++++++++++--------------------------------- 1 file changed, 33 insertions(+), 75 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index aae398dbda..0f8e33940f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -137,14 +137,11 @@ void invalidate_vuid(uint16 vuid) /* same number of igroups as groups */ vuser->n_groups = 0; - if (vuser->groups && (vuser->groups != (gid_t *)vuser->igroups)) - free(vuser->groups); + if (vuser->groups) free(vuser->groups); - if (vuser->igroups) free(vuser->igroups); - if (vuser->sids ) free(vuser->sids); + if (vuser->sids) free(vuser->sids); vuser->sids = NULL; - vuser->igroups = NULL; vuser->groups = NULL; } @@ -164,78 +161,41 @@ char *validated_username(uint16 vuid) /**************************************************************************** Setup the groups a user belongs to. ****************************************************************************/ -int setup_groups(char *user, int uid, int gid, int *p_ngroups, - int **p_igroups, gid_t **p_groups) +int setup_groups(char *user, int uid, int gid, int *p_ngroups, GID_T **p_groups) { - if (-1 == initgroups(user,gid)) - { - if (getuid() == 0) - { - DEBUG(0,("Unable to initgroups!\n")); - if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000) - DEBUG(0,("This is probably a problem with the account %s\n",user)); + int i,ngroups; + GID_T *groups; + GID_T grp = 0; + + if (-1 == initgroups(user,gid)) { + if (getuid() == 0) { + DEBUG(0,("Unable to initgroups!\n")); + if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000) { + DEBUG(0,("This is probably a problem with the account %s\n", + user)); + } + } + return -1; } - } - else - { - int i,ngroups; - int *igroups; - gid_t grp = 0; - ngroups = getgroups(0,&grp); - if (ngroups <= 0) - ngroups = 32; - igroups = (int *)malloc(sizeof(int)*ngroups); - for (i=0;i 0) - { - /* does getgroups return ints or gid_t ?? */ - static BOOL groups_use_ints = True; - if (groups_use_ints && - ngroups == 1 && - SVAL(igroups,2) == 0x4242) - groups_use_ints = False; - - for (i=0;groups_use_ints && in_groups = 0; vuser->groups = NULL; - vuser->igroups = NULL; /* Find all the groups this uid is in and store them. Used by become_user() */ setup_groups(unix_name,uid,gid, &vuser->n_groups, - &vuser->igroups, &vuser->groups); DEBUG(3,("uid %d registered to name %s\n",uid,unix_name)); -- cgit From fa88efbbacbbe74b72ddb9e316265de2aab31260 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 10 Aug 1998 07:04:53 +0000 Subject: split the system password checking routines out of smbd/password.c and into passdb/pass_check.c. This means SWAT no longer needs to link to smbd/password.c (This used to be commit 90d93889d722670cbb517017531264630af759bf) --- source3/smbd/password.c | 1182 ++++++----------------------------------------- 1 file changed, 141 insertions(+), 1041 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0f8e33940f..055c53d009 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -36,11 +36,6 @@ static pstring session_users=""; extern pstring global_myname; extern fstring global_myworkgroup; -/* these are kept here to keep the string_combinations function simple */ -static char this_user[100]=""; -static char this_salt[100]=""; -static char this_crypted[100]=""; - /* Data to do lanman1/2 password challenge. */ static unsigned char saved_challenge[8]; static BOOL challenge_sent=False; @@ -305,779 +300,36 @@ void add_session_user(char *user) } -#ifdef OSF1_ENH_SEC -/**************************************************************************** -an enhanced crypt for OSF1 -****************************************************************************/ -static char *osf1_bigcrypt(char *password,char *salt1) -{ - static char result[AUTH_MAX_PASSWD_LENGTH] = ""; - char *p1; - char *p2=password; - char salt[3]; - int i; - int parts = strlen(password) / AUTH_CLEARTEXT_SEG_CHARS; - if (strlen(password)%AUTH_CLEARTEXT_SEG_CHARS) - parts++; - - StrnCpy(salt,salt1,2); - StrnCpy(result,salt1,2); - - for (i=0; iufld.fd_slogin = starttime; - mypasswd->ufld.fd_nlogins = 0; - - putprpwnam(user,mypasswd); - - DEBUG(3,("Update protected database for Account %s after succesful connection\n",user)); - } - else - { - mypasswd->ufld.fd_ulogin = starttime; - mypasswd->ufld.fd_nlogins = mypasswd->ufld.fd_nlogins + 1; - if ( mypasswd->ufld.fd_max_tries != 0 && mypasswd->ufld.fd_nlogins > mypasswd->ufld.fd_max_tries ) - { - mypasswd->uflg.fg_lock = 0; - DEBUG(3,("Account is disabled -- see Account Administrator.\n")); - } - putprpwnam ( user , mypasswd ); - DEBUG(3,("Update protected database for Account %s after refusing connection\n",user)); - } -#else - DEBUG(6,("Updated database with %s %s\n",user,BOOLSTR(result))); -#endif -} - - -#ifdef HAVE_PAM -/******************************************************************* -check on PAM authentication -********************************************************************/ - -/* We first need some helper functions */ -#include -/* Static variables used to communicate between the conversation function - * and the server_login function - */ -static char *PAM_username; -static char *PAM_password; - -/* PAM conversation function - * Here we assume (for now, at least) that echo on means login name, and - * echo off means password. - */ -static int PAM_conv (int num_msg, - const struct pam_message **msg, - struct pam_response **resp, - void *appdata_ptr) { - int replies = 0; - struct pam_response *reply = NULL; - - #define COPY_STRING(s) (s) ? strdup(s) : NULL - - reply = malloc(sizeof(struct pam_response) * num_msg); - if (!reply) return PAM_CONV_ERR; - - for (replies = 0; replies < num_msg; replies++) { - switch (msg[replies]->msg_style) { - case PAM_PROMPT_ECHO_ON: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_username); - /* PAM frees resp */ - break; - case PAM_PROMPT_ECHO_OFF: - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = COPY_STRING(PAM_password); - /* PAM frees resp */ - break; - case PAM_TEXT_INFO: - /* fall through */ - case PAM_ERROR_MSG: - /* ignore it... */ - reply[replies].resp_retcode = PAM_SUCCESS; - reply[replies].resp = NULL; - break; - default: - /* Must be an error of some sort... */ - free (reply); - return PAM_CONV_ERR; - } - } - if (reply) *resp = reply; - return PAM_SUCCESS; -} -static struct pam_conv PAM_conversation = { - &PAM_conv, - NULL -}; - - -static BOOL pam_auth(char *this_user,char *password) +BOOL update_smbpassword_file(char *user, char *password) { - pam_handle_t *pamh; - int pam_error; - - /* Now use PAM to do authentication. For now, we won't worry about - * session logging, only authentication. Bail out if there are any - * errors. Since this is a limited protocol, and an even more limited - * function within a server speaking this protocol, we can't be as - * verbose as would otherwise make sense. - * Query: should we be using PAM_SILENT to shut PAM up? - */ - #define PAM_BAIL if (pam_error != PAM_SUCCESS) { \ - pam_end(pamh, 0); return False; \ - } - PAM_password = password; - PAM_username = this_user; - pam_error = pam_start("samba", this_user, &PAM_conversation, &pamh); - PAM_BAIL; -/* Setting PAM_SILENT stops generation of error messages to syslog - * to enable debugging on Red Hat Linux set: - * /etc/pam.d/samba: - * auth required /lib/security/pam_pwdb.so nullok shadow audit - * _OR_ change PAM_SILENT to 0 to force detailed reporting (logging) - */ - pam_error = pam_authenticate(pamh, PAM_SILENT); - PAM_BAIL; - /* It is not clear to me that account management is the right thing - * to do, but it is not clear that it isn't, either. This can be - * removed if no account management should be done. Alternately, - * put a pam_allow.so entry in /etc/pam.conf for account handling. */ - pam_error = pam_acct_mgmt(pamh, PAM_SILENT); - PAM_BAIL; - pam_end(pamh, PAM_SUCCESS); - /* If this point is reached, the user has been authenticated. */ - return(True); -} -#endif - - -#ifdef WITH_AFS -/******************************************************************* -check on AFS authentication -********************************************************************/ -static BOOL afs_auth(char *this_user,char *password) -{ - long password_expires = 0; - char *reason; - - /* For versions of AFS prior to 3.3, this routine has few arguments, */ - /* but since I can't find the old documentation... :-) */ - setpag(); - if (ka_UserAuthenticateGeneral(KA_USERAUTH_VERSION+KA_USERAUTH_DOSETPAG, - this_user, - (char *) 0, /* instance */ - (char *) 0, /* cell */ - password, - 0, /* lifetime, default */ - &password_expires, /*days 'til it expires */ - 0, /* spare 2 */ - &reason) == 0) - return(True); - return(False); -} -#endif - - -#ifdef WITH_DFS - -/***************************************************************** - This new version of the DFS_AUTH code was donated by Karsten Muuss - . It fixes the following problems with the - old code : - - - Server credentials may expire - - Client credential cache files have wrong owner - - purge_context() function is called with invalid argument - - This new code was modified to ensure that on exit the uid/gid is - still root, and the original directory is restored. JRA. -******************************************************************/ - -sec_login_handle_t my_dce_sec_context; -int dcelogin_atmost_once = 0; - -/******************************************************************* -check on a DCE/DFS authentication -********************************************************************/ -static BOOL dfs_auth(char *this_user,char *password) -{ - error_status_t err; - int err2; - int prterr; - signed32 expire_time, current_time; - boolean32 password_reset; - struct passwd *pw; - sec_passwd_rec_t passwd_rec; - sec_login_auth_src_t auth_src = sec_login_auth_src_network; - unsigned char dce_errstr[dce_c_error_string_len]; - - if (dcelogin_atmost_once) return(False); - -#ifdef HAVE_CRYPT - /* - * We only go for a DCE login context if the given password - * matches that stored in the local password file.. - * Assumes local passwd file is kept in sync w/ DCE RGY! - */ - - if ( strcmp((char *)crypt(password,this_salt),this_crypted) ) - return(False); -#endif - - sec_login_get_current_context(&my_dce_sec_context, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get current context. %s\n", dce_errstr)); - - return(False); - } - - sec_login_certify_identity(my_dce_sec_context, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get current context. %s\n", dce_errstr)); - - return(False); - } - - sec_login_get_expiration(my_dce_sec_context, &expire_time, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr)); - - return(False); - } - - time(¤t_time); - - if (expire_time < (current_time + 60)) { - struct passwd *pw; - sec_passwd_rec_t *key; - - sec_login_get_pwent(my_dce_sec_context, - (sec_login_passwd_t*)&pw, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); - - return(False); - } - - sec_login_refresh_identity(my_dce_sec_context, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't refresh identity. %s\n", dce_errstr)); - - return(False); - } - - sec_key_mgmt_get_key(rpc_c_authn_dce_secret, NULL, - (unsigned char *)pw->pw_name, - sec_c_key_version_none, - (void**)&key, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get key for %s. %s\n", pw->pw_name, dce_errstr)); - - return(False); - } - - sec_login_valid_and_cert_ident(my_dce_sec_context, key, - &password_reset, &auth_src, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't validate and certify identity for %s. %s\n", - pw->pw_name, dce_errstr)); - } - - sec_key_mgmt_free_key(key, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't free key.\n", dce_errstr)); - } - } - - if (sec_login_setup_identity((unsigned char *)this_user, - sec_login_no_flags, - &my_dce_sec_context, - &err) == 0) - - { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE Setup Identity for %s failed: %s\n", - this_user,dce_errstr)); - return(False); - } - - sec_login_get_pwent(my_dce_sec_context, - (sec_login_passwd_t*)&pw, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); - - return(False); - } - - sec_login_purge_context(&my_dce_sec_context, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't purge context. %s\n", dce_errstr)); - - return(False); - } - - /* - * NB. I'd like to change these to call something like become_user() - * instead but currently we don't have a connection - * context to become the correct user. This is already - * fairly platform specific code however, so I think - * this should be ok. I have added code to go - * back to being root on error though. JRA. - */ - - if (setregid(-1, pw->pw_gid) != 0) { - DEBUG(0,("Can't set egid to %d (%s)\n", pw->pw_gid, strerror(errno))); - return False; - } - - if (setreuid(-1, pw->pw_uid) != 0) { - setgid(0); - DEBUG(0,("Can't set euid to %d (%s)\n", pw->pw_uid, strerror(errno))); - return False; - } - - if (sec_login_setup_identity((unsigned char *)this_user, - sec_login_no_flags, - &my_dce_sec_context, - &err) == 0) - - { - dce_error_inq_text(err, dce_errstr, &err2); - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - DEBUG(0,("DCE Setup Identity for %s failed: %s\n", - this_user,dce_errstr)); - return(False); - } - - sec_login_get_pwent(my_dce_sec_context, - (sec_login_passwd_t*)&pw, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); - - return(False); - } - - passwd_rec.version_number = sec_passwd_c_version_none; - passwd_rec.pepper = NULL; - passwd_rec.key.key_type = sec_passwd_plain; - passwd_rec.key.tagged_union.plain = (idl_char *)password; - - sec_login_validate_identity(my_dce_sec_context, - &passwd_rec, &password_reset, - &auth_src, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - DEBUG(0,("DCE Identity Validation failed for principal %s: %s\n", - this_user,dce_errstr)); - - return(False); - } - - sec_login_certify_identity(my_dce_sec_context, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - DEBUG(0,("DCE certify identity failed: %s\n", dce_errstr)); - - return(False); - } - - if (auth_src != sec_login_auth_src_network) { - DEBUG(0,("DCE context has no network credentials.\n")); - } - - sec_login_set_context(my_dce_sec_context, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE login failed for principal %s, cant set context: %s\n", - this_user,dce_errstr)); - - sec_login_purge_context(&my_dce_sec_context, &err); - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - return(False); - } - - sec_login_get_pwent(my_dce_sec_context, - (sec_login_passwd_t*)&pw, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE can't get pwent. %s\n", dce_errstr)); - - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - return(False); - } - - DEBUG(0,("DCE login succeeded for principal %s on pid %d\n", - this_user, getpid())); - - DEBUG(3,("DCE principal: %s\n" - " uid: %d\n" - " gid: %d\n", - pw->pw_name, pw->pw_uid, pw->pw_gid)); - DEBUG(3,(" info: %s\n" - " dir: %s\n" - " shell: %s\n", - pw->pw_gecos, pw->pw_dir, pw->pw_shell)); - - sec_login_get_expiration(my_dce_sec_context, &expire_time, &err); - if (err != error_status_ok ) { - dce_error_inq_text(err, dce_errstr, &err2); - /* Go back to root, JRA. */ - setuid(0); - setgid(0); - DEBUG(0,("DCE can't get expiration. %s\n", dce_errstr)); - - return(False); - } - - setuid(0); - setgid(0); - - DEBUG(0,("DCE context expires: %s",asctime(localtime(&expire_time)))); - - dcelogin_atmost_once = 1; - return (True); -} - -void dfs_unlogin(void) -{ - error_status_t err; - int err2; - unsigned char dce_errstr[dce_c_error_string_len]; - - sec_login_purge_context(&my_dce_sec_context, &err); - if (err != error_status_ok ) - { - dce_error_inq_text(err, dce_errstr, &err2); - DEBUG(0,("DCE purge login context failed for server instance %d: %s\n", - getpid(), dce_errstr)); - } -} -#endif - -#ifdef KRB5_AUTH -/******************************************************************* -check on Kerberos authentication -********************************************************************/ -static BOOL krb5_auth(char *this_user,char *password) -{ - krb5_data tgtname = { - 0, - KRB5_TGS_NAME_SIZE, - KRB5_TGS_NAME - }; - krb5_context kcontext; - krb5_principal kprinc; - krb5_principal server; - krb5_creds kcreds; - int options = 0; - krb5_address **addrs = (krb5_address **)0; - krb5_preauthtype *preauth = NULL; - krb5_keytab keytab = NULL; - krb5_timestamp now; - krb5_ccache ccache = NULL; - int retval; - char *name; - - if ( retval=krb5_init_context(&kcontext)) - { - return(False); - } - - if ( retval = krb5_timeofday(kcontext, &now) ) - { - return(False); - } - - if ( retval = krb5_cc_default(kcontext, &ccache) ) - { - return(False); - } + struct smb_passwd *smbpw; + BOOL ret; - if ( retval = krb5_parse_name(kcontext, this_user, &kprinc) ) - { - return(False); - } - - memset((char *)&kcreds, 0, sizeof(kcreds)); - - kcreds.client = kprinc; + become_root(0); + smbpw = getsmbpwnam(user); + unbecome_root(0); - if ((retval = krb5_build_principal_ext(kcontext, &server, - krb5_princ_realm(kcontext, kprinc)->length, - krb5_princ_realm(kcontext, kprinc)->data, - tgtname.length, - tgtname.data, - krb5_princ_realm(kcontext, kprinc)->length, - krb5_princ_realm(kcontext, kprinc)->data, - 0))) - { - return(False); + if(smbpw == NULL) { + DEBUG(0,("getsmbpwnam returned NULL\n")); + return False; } - - kcreds.server = server; - - retval = krb5_get_in_tkt_with_password(kcontext, - options, - addrs, - NULL, - preauth, - password, - 0, - &kcreds, - 0); - - if ( retval ) - { - return(False); + + /* Here, the flag is one, because we want to ignore the + XXXXXXX'd out password */ + ret = change_oem_password( smbpw, password, True); + if (ret == False) { + DEBUG(3,("change_oem_password returned False\n")); } - return(True); -} -#endif /* KRB5_AUTH */ - -#ifdef KRB4_AUTH -/******************************************************************* -check on Kerberos authentication -********************************************************************/ -static BOOL krb4_auth(char *this_user,char *password) -{ - char realm[REALM_SZ]; - char tkfile[MAXPATHLEN]; - - if (krb_get_lrealm(realm, 1) != KSUCCESS) - (void) safe_strcpy(realm, KRB_REALM, sizeof (realm) - 1); - - (void) slprintf(tkfile, sizeof(tkfile) - 1, "/tmp/samba_tkt_%d", getpid()); - - krb_set_tkt_string(tkfile); - if (krb_verify_user(this_user, "", realm, - password, 0, - "rmcd") == KSUCCESS) { - unlink(tkfile); - return 1; - } - unlink(tkfile); - return 0; -} -#endif /* KRB4_AUTH */ - -#ifdef LINUX_BIGCRYPT -/**************************************************************************** -an enhanced crypt for Linux to handle password longer than 8 characters -****************************************************************************/ -static int linux_bigcrypt(char *password,char *salt1, char *crypted) -{ -#define LINUX_PASSWORD_SEG_CHARS 8 - char salt[3]; - int i; - - StrnCpy(salt,salt1,2); - crypted +=2; - - for ( i=strlen(password); i > 0; i -= LINUX_PASSWORD_SEG_CHARS) { - char * p = crypt(password,salt) + 2; - if (strncmp(p, crypted, LINUX_PASSWORD_SEG_CHARS) != 0) - return(0); - password += LINUX_PASSWORD_SEG_CHARS; - crypted += strlen(p); - } - - return(1); + return ret; } -#endif - - -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static BOOL string_combinations2(char *s,int offset,BOOL (*fn)(char *),int N) -{ - int len = strlen(s); - int i; - -#ifdef PASSWORD_LENGTH - len = MIN(len,PASSWORD_LENGTH); -#endif - - if (N <= 0 || offset >= len) - return(fn(s)); - - for (i=offset;i<(len-(N-1));i++) - { - char c = s[i]; - if (!islower(c)) continue; - s[i] = toupper(c); - if (string_combinations2(s,i+1,fn,N-1)) - return(True); - s[i] = c; - } - return(False); -} - -/**************************************************************************** -apply a function to upper/lower case combinations -of a string and return true if one of them returns true. -try all combinations with up to N uppercase letters. -offset is the first char to try and change (start with 0) -it assumes the string starts lowercased -****************************************************************************/ -static BOOL string_combinations(char *s,BOOL (*fn)(char *),int N) -{ - int n; - for (n=1;n<=N;n++) - if (string_combinations2(s,0,fn,n)) return(True); - return(False); -} - - - -/**************************************************************************** -core of password checking routine -****************************************************************************/ -BOOL password_check(char *password) -{ - -#ifdef HAVE_PAM -/* This falls through if the password check fails - - if HAVE_CRYPT is not defined this causes an error msg - saying Warning - no crypt available - - if HAVE_CRYPT is defined this is a potential security hole - as it may authenticate via the crypt call when PAM - settings say it should fail. - if (pam_auth(this_user,password)) return(True); - Hence we make a direct return to avoid a second chance!!! -*/ - return (pam_auth(this_user,password)); -#endif - -#ifdef WITH_AFS - if (afs_auth(this_user,password)) return(True); -#endif -#ifdef WITH_DFS - if (dfs_auth(this_user,password)) return(True); -#endif -#ifdef KRB5_AUTH - if (krb5_auth(this_user,password)) return(True); -#endif -#ifdef KRB4_AUTH - if (krb4_auth(this_user,password)) return(True); -#endif -#ifdef OSF1_ENH_SEC - { - BOOL ret = (strcmp(osf1_bigcrypt(password,this_salt),this_crypted) == 0); - if(!ret) { - DEBUG(2,("password_check: OSF1_ENH_SEC failed. Trying normal crypt.\n")); - ret = (strcmp((char *)crypt(password,this_salt),this_crypted) == 0); - } - return ret; - } -#endif - -#ifdef ULTRIX_AUTH - return (strcmp((char *)crypt16(password, this_salt ),this_crypted) == 0); -#endif - -#ifdef LINUX_BIGCRYPT - return(linux_bigcrypt(password,this_salt,this_crypted)); -#endif - -#ifdef HAVE_BIGCRYPT - return(strcmp(bigcrypt(password,this_salt),this_crypted) == 0); -#endif - -#ifndef HAVE_CRYPT - DEBUG(1,("Warning - no crypt available\n")); - return(False); -#else - return(strcmp((char *)crypt(password,this_salt),this_crypted) == 0); -#endif -} /**************************************************************************** core of smb password checking routine. @@ -1125,327 +377,175 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ - BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar lm_pass[24], uchar nt_pass[24]) { - uchar challenge[8]; + uchar challenge[8]; - if (!lm_pass || !smb_pass) return(False); + if (!lm_pass || !smb_pass) return(False); - if(smb_pass->acct_ctrl & ACB_DISABLED) - { - DEBUG(3,("smb_password_ok: account for user %s was disabled.\n", smb_pass->smb_name)); - return(False); - } - - if (!last_challenge(challenge)) - { - DEBUG(1,("smb_password_ok: no challenge done - password failed\n")); - return False; - } + if(smb_pass->acct_ctrl & ACB_DISABLED) { + DEBUG(3,("account for user %s was disabled.\n", + smb_pass->smb_name)); + return(False); + } - DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n", smb_pass->smb_name)); + if (!last_challenge(challenge)) { + DEBUG(1,("no challenge done - password failed\n")); + return False; + } - if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) - { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check((char *)nt_pass, (uchar *)smb_pass->smb_nt_passwd, challenge)) - { - DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); - return(True); - } - DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); - } + DEBUG(4,("Checking SMB password for user %s\n", + smb_pass->smb_name)); + + if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); + if (smb_password_check((char *)nt_pass, + (uchar *)smb_pass->smb_nt_passwd, + challenge)) { + DEBUG(4,("NT MD4 password check succeeded\n")); + return(True); + } + DEBUG(4,("NT MD4 password check failed\n")); + } - /* Try against the lanman password. smb_pass->smb_passwd == NULL means - no password, allow access. */ + /* Try against the lanman password. smb_pass->smb_passwd == NULL means + no password, allow access. */ - DEBUG(4,("Checking LM MD4 password\n")); + DEBUG(4,("Checking LM MD4 password\n")); - if((smb_pass->smb_passwd == NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ)) - { - DEBUG(4,("smb_password_ok: no password required for user %s\n", smb_pass->smb_name)); - return True; - } + if((smb_pass->smb_passwd == NULL) && + (smb_pass->acct_ctrl & ACB_PWNOTREQ)) { + DEBUG(4,("no password required for user %s\n", + smb_pass->smb_name)); + return True; + } - if((smb_pass->smb_passwd != NULL) && smb_password_check((char *)lm_pass, (uchar *)smb_pass->smb_passwd, challenge)) - { - DEBUG(4,("smb_password_ok: LM MD4 password check succeeded\n")); - return(True); - } + if((smb_pass->smb_passwd != NULL) && + smb_password_check((char *)lm_pass, + (uchar *)smb_pass->smb_passwd, challenge)) { + DEBUG(4,("LM MD4 password check succeeded\n")); + return(True); + } - DEBUG(4,("smb_password_ok: LM MD4 password check failed\n")); + DEBUG(4,("LM MD4 password check failed\n")); - return False; + return False; } + /**************************************************************************** -check if a username/password is OK +check if a username/password is OK assuming the password is a 24 byte +SMB hash +return True if the password is correct, False otherwise ****************************************************************************/ -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) +static BOOL pass_check_smb(char *user,char *password, struct passwd *pwd) { - pstring pass2; - int level = lp_passwordlevel(); - struct passwd *pass; - uchar challenge[8]; - struct smb_passwd *smb_pass; - BOOL update_encrypted = lp_update_encrypted(); - BOOL challenge_done = False; + struct passwd *pass; + uchar challenge[8]; + struct smb_passwd *smb_pass; + BOOL challenge_done; - if (password) password[pwlen] = 0; - - if (pwlen == 24) - challenge_done = last_challenge(challenge); - -#if DEBUG_PASSWORD - if (challenge_done) - { - int i; - DEBUG(100,("checking user=[%s] pass=[",user)); - for( i = 0; i < 24; i++) - DEBUG(100,("%0x ", (unsigned char)password[i])); - DEBUG(100,("]\n")); - } else { - DEBUG(100,("checking user=[%s] pass=[%s]\n",user,password)); - } -#endif - - if (!password) - return(False); - - if (((!*password) || (!pwlen)) && !lp_null_passwords()) - return(False); - - if (pwd && !user) - { - pass = (struct passwd *) pwd; - user = pass->pw_name; - } - else - pass = Get_Pwnam(user,True); - - DEBUG(4,("SMB Password - pwlen = %d, challenge_done = %d\n", pwlen, challenge_done)); + if (!password) { + return(False); + } - if ((pwlen == 24) && challenge_done) - { - DEBUG(4,("Checking SMB password for user %s (l=24)\n",user)); + challenge_done = last_challenge(challenge); - if (!pass) - { - DEBUG(3,("Couldn't find user %s\n",user)); - return(False); + if (!challenge_done) { + DEBUG(0,("Error: challenge not done for user=%s\n", user)); + return False; } - smb_pass = getsmbpwnam(user); + if (pwd && !user) { + pass = (struct passwd *) pwd; + user = pass->pw_name; + } else { + pass = Get_Pwnam(user,True); + } - if (!smb_pass) - { - DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); - return(False); + if (!pass) { + DEBUG(3,("Couldn't find user %s\n",user)); + return(False); } - /* Quit if the account was disabled. */ - if(smb_pass->acct_ctrl & ACB_DISABLED) - { - DEBUG(3,("password_ok: account for user %s was disabled.\n", user)); - return(False); - } + smb_pass = getsmbpwnam(user); - /* Ensure the uid's match */ - if (smb_pass->smb_userid != pass->pw_uid) - { - DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); - return(False); + if (!smb_pass) { + DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); + return(False); } - if(smb_password_ok( smb_pass, (unsigned char *)password,(uchar *)password)) - { - update_protected_database(user,True); - return(True); + /* Quit if the account was disabled. */ + if(smb_pass->acct_ctrl & ACB_DISABLED) { + DEBUG(3,("account for user %s was disabled.\n", user)); + return(False); } - DEBUG(3,("Error smb_password_check failed\n")); - } - - DEBUG(4,("Checking password for user %s (l=%d)\n",user,pwlen)); - - if (!pass) - { - DEBUG(3,("Couldn't find user %s\n",user)); - return(False); - } - -#ifdef HAVE_GETSPNAM - { - struct spwd *spass; - - /* many shadow systems require you to be root to get the password, - in most cases this should already be the case when this - function is called, except perhaps for IPC password changing - requests */ - - spass = getspnam(pass->pw_name); - if (spass && spass->sp_pwdp) - pass->pw_passwd = spass->sp_pwdp; - } -#elif defined(IA_UINFO) - { - /* Need to get password with SVR4.2's ia_ functions instead of - get{sp,pw}ent functions. Required by UnixWare 2.x, tested on - version 2.1. (tangent@cyberport.com) */ - uinfo_t uinfo; - if (ia_openinfo(pass->pw_name, &uinfo) != -1) - ia_get_logpwd(uinfo, &(pass->pw_passwd)); - } -#endif - -#ifdef HAVE_GETPRPWNAM - { - struct pr_passwd *pr_pw = getprpwnam(pass->pw_name); - if (pr_pw && pr_pw->ufld.fd_encrypt) - pass->pw_passwd = pr_pw->ufld.fd_encrypt; - } -#endif - -#ifdef OSF1_ENH_SEC - { - struct pr_passwd *mypasswd; - DEBUG(5,("Checking password for user %s in OSF1_ENH_SEC\n",user)); - mypasswd = getprpwnam (user); - if ( mypasswd ) - { - fstrcpy(pass->pw_name,mypasswd->ufld.fd_name); - fstrcpy(pass->pw_passwd,mypasswd->ufld.fd_encrypt); - } - else - { - DEBUG(5,("No entry for user %s in protected database !\n",user)); - return(False); - } - } -#endif - -#ifdef ULTRIX_AUTH - { - AUTHORIZATION *ap = getauthuid( pass->pw_uid ); - if (ap) - { - fstrcpy( pass->pw_passwd, ap->a_password ); - endauthent(); - } - } -#endif - - /* extract relevant info */ - fstrcpy(this_user,pass->pw_name); - fstrcpy(this_salt,pass->pw_passwd); - /* crypt on some platforms (HPUX in particular) - won't work with more than 2 salt characters. */ - this_salt[2] = 0; - - fstrcpy(this_crypted,pass->pw_passwd); - - if (!*this_crypted) { - if (!lp_null_passwords()) { - DEBUG(2,("Disallowing access to %s due to null password\n",this_user)); - return(False); - } - if (!*password) { - DEBUG(3,("Allowing access to %s with null password\n",this_user)); - return(True); - } - } - - /* try it as it came to us */ - if (password_check(password)) - { - update_protected_database(user,True); - if (update_encrypted) - update_smbpassword_file(user,password); - return(True); - } - - /* if the password was given to us with mixed case then we don't - need to proceed as we know it hasn't been case modified by the - client */ - if (strhasupper(password) && strhaslower(password)) - return(False); - - /* make a copy of it */ - StrnCpy(pass2,password,sizeof(pstring)-1); - - /* try all lowercase */ - strlower(password); - if (password_check(password)) - { - update_protected_database(user,True); - if (update_encrypted) - update_smbpassword_file(user,password); - return(True); - } - - /* give up? */ - if (level < 1) - { - update_protected_database(user,False); - - /* restore it */ - fstrcpy(password,pass2); - - return(False); - } - - /* last chance - all combinations of up to level chars upper! */ - strlower(password); - - if (string_combinations(password,password_check,level)) - { - update_protected_database(user,True); - if (update_encrypted) - update_smbpassword_file(user,password); - return(True); - } + /* Ensure the uid's match */ + if (smb_pass->smb_userid != pass->pw_uid) { + DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); + return(False); + } - update_protected_database(user,False); - - /* restore it */ - fstrcpy(password,pass2); - - return(False); + if (smb_password_ok(smb_pass, + (unsigned char *)password, + (uchar *)password)) { + return(True); + } + + DEBUG(3,("Error smb_password_check failed\n")); + return False; } - +/**************************************************************************** +check if a username/password pair is OK either via the system password +database or the encrypted SMB password database +return True if the password is correct, False otherwise +****************************************************************************/ +BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) +{ + if (pwlen == 24) { + /* if it is 24 bytes long then assume it is an encrypted + password */ + return pass_check_smb(user, password, pwd); + } + + return pass_check(user, password, pwlen, pwd, + lp_update_encrypted() ? + update_smbpassword_file : NULL); +} /**************************************************************************** check if a username is valid ****************************************************************************/ BOOL user_ok(char *user,int snum) { - pstring valid, invalid; - BOOL ret; - - StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)); - StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)); + pstring valid, invalid; + BOOL ret; - string_sub(valid,"%S",lp_servicename(snum)); - string_sub(invalid,"%S",lp_servicename(snum)); + StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)); + StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)); - ret = !user_in_list(user,invalid); - - if (ret && valid && *valid) - ret = user_in_list(user,valid); + string_sub(valid,"%S",lp_servicename(snum)); + string_sub(invalid,"%S",lp_servicename(snum)); + + ret = !user_in_list(user,invalid); + + if (ret && valid && *valid) { + ret = user_in_list(user,valid); + } - if (ret && lp_onlyuser(snum)) { - char *user_list = lp_username(snum); - string_sub(user_list,"%S",lp_servicename(snum)); - ret = user_in_list(user,user_list); - } + if (ret && lp_onlyuser(snum)) { + char *user_list = lp_username(snum); + string_sub(user_list,"%S",lp_servicename(snum)); + ret = user_in_list(user,user_list); + } - return(ret); + return(ret); } -- cgit From b067f0e2b921a7ac221d47a91d408526935363b2 Mon Sep 17 00:00:00 2001 From: "Christopher R. Hertel" Date: Thu, 13 Aug 1998 00:01:02 +0000 Subject: Debug output formatting change. I'm trying to combine log lines that really should be together. Chris -)----- (This used to be commit 8880fc58fa61edfd5a83cc75ef627b430b8a4437) --- source3/smbd/password.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 055c53d009..118251ffd6 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -184,11 +184,11 @@ int setup_groups(char *user, int uid, int gid, int *p_ngroups, GID_T **p_groups) (*p_groups) = groups; - DEBUG(3,("%s is in %d groups\n",user,ngroups)); - for (i=0;i Date: Sat, 15 Aug 1998 01:19:26 +0000 Subject: configure: Changes for extra headers. configure.in: Source for header changes. client/clitar.c: Fixed isXXX macros & debugs for gcc pedantic compile. include/config.h.in: Added MEMSET, BZERO, MEMORY, RPCSVC_YPCLNT, STRINGS headers. include/includes.h: Headers for the above. include/smb.h: Made SIGNAL_CAST POSIX by default void (*)(int). lib/access.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/charset.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/debug.c: Fixed signal functs. lib/kanji.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/smbrun.c: Fixed isXXX macros & debugs for gcc pedantic compile. lib/util.c: Fixed isXXX macros & debugs for gcc pedantic compile. libsmb/namequery.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem.c: Fixed isXXX macros & debugs for gcc pedantic compile. locking/shmem_sysv.c: Fixed error messages in sysV stuff. nmbd/asyncdns.c: Fixed signal functs. nmbd/nmbd.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/passdb.c: Fixed isXXX macros & debugs for gcc pedantic compile. passdb/smbpassfile.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/chgpasswd.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/ipc.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/nttrans.c: Fixed fsp code path. smbd/password.c: fixed HAVE_YP_GET_DEFAULT_DOMAIN problem. smbd/printing.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/reply.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/server.c: Fixed isXXX macros & debugs for gcc pedantic compile. smbd/trans2.c: Fixed core dump bug. smbd/uid.c: Fixed isXXX macros & debugs for gcc pedantic compile. Jeremy. (This used to be commit 1b9cbcd02e575dc0a95fa589f720df30a4acc46b) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 118251ffd6..121ebb7f00 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -829,7 +829,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { BOOL host_ok = False; -#ifdef HAVE_NETGROUP +#if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN) if (is_group) { static char *mydomain = NULL; -- cgit From 8afc9c80ac11649f06e5517d819dbf201c941acb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 24 Aug 1998 21:49:10 +0000 Subject: Changed ASSERT macros to SMB_ASSERT macros as some systems already have an ASSERT macro defined. Jeremy. (This used to be commit dbe6ad014a8b5dcbf17d7cd9865650c2e040d666) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 121ebb7f00..ecc86f29ec 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1191,8 +1191,8 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); trust_password_unlock(); /* - * Here we should check the last change time to see if the machine - * password needs changing..... TODO... JRA. + * Here we check the last change time to see if the machine + * password needs changing. JRA. */ if(time(NULL) > lct + lp_machine_password_timeout()) -- cgit From 5e5e320d361afcb4d9503354b3912b4c7a672197 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 27 Aug 1998 20:38:53 +0000 Subject: This is the stat cache code - seems to work fine (needs heavy NetBench testing though.... :-). Attempts to efficiently reduce the number of stat() calls Samba does. Jeremy. (This used to be commit d0e48a2d8072c3e77a57ac6a2fb5044c05f03b41) --- source3/smbd/password.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ecc86f29ec..4ee9e8705d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,10 +21,6 @@ #include "includes.h" -#if (defined(HAVE_NETGROUP) && defined (WITH_AUTOMOUNT)) -#include "rpcsvc/ypclnt.h" -#endif - extern int DEBUGLEVEL; extern int Protocol; -- cgit From 61b5fd6f32e9ccb612df1354a3e3b3bed5f2b808 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 31 Aug 1998 03:11:42 +0000 Subject: bounds check next_token() to prevent possible buffer overflows (This used to be commit 3eade55dc7c842bdc50205c330802d211fae54d3) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4ee9e8705d..dadbcad11e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -934,7 +934,7 @@ struct cli_state *server_cryptkey(void) return NULL; p = lp_passwordserver(); - while(p && next_token( &p, desthost, LIST_SEP)) { + while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { standard_sub_basic(desthost); strupper(desthost); @@ -1214,7 +1214,7 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); */ p = lp_passwordserver(); - while(p && next_token( &p, remote_machine, LIST_SEP)) { + while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { standard_sub_basic(remote_machine); strupper(remote_machine); -- cgit From e9ea36e4d2270bd7d32da12ef6d6e2299641582d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 05:07:05 +0000 Subject: tridge the destroyer returns! prompted by the interpret_security() dead code that Jean-Francois pointed out I added a make target "finddead" that finds potentially dead (ie. unused) code. It spat out 304 function names ... I went through these are deleted many of them, making others static (finddead also reports functions that are used only in the local file). in doing this I have almost certainly deleted some useful code. I may have even prevented compilation with some compile options. I apologise. I decided it was better to get rid of this code now and add back the one or two functions that are needed than to keep all this baggage. So, if I have done a bit too much "destroying" then let me know. Keep the swearing to a minimum :) One bit I didn't do is the ubibt code. Chris, can you look at that? Heaps of unused functions there. Can they be made static? (This used to be commit 2204475c87f3024ea8fd1fbd7385b2def617a46f) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index dadbcad11e..684420f4c3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -84,7 +84,7 @@ BOOL set_challenge(char *challenge) /******************************************************************* get the last challenge sent ********************************************************************/ -BOOL last_challenge(unsigned char *challenge) +static BOOL last_challenge(unsigned char *challenge) { if (!challenge_sent) return(False); memcpy(challenge,saved_challenge,8); @@ -299,7 +299,7 @@ void add_session_user(char *user) /**************************************************************************** update the encrypted smbpasswd file from the plaintext username and password *****************************************************************************/ -BOOL update_smbpassword_file(char *user, char *password) +static BOOL update_smbpassword_file(char *user, char *password) { struct smb_passwd *smbpw; BOOL ret; -- cgit From f6044c87c021342d68d614d59bc8dacd32d223b9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Sep 1998 13:24:20 +0000 Subject: some cleanups to use ZERO_STRUCT() and friends (This used to be commit 7b154dc4313324dfad6cf0117b8ce246bf12bf16) --- source3/smbd/password.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 684420f4c3..1d90af3066 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1202,7 +1202,8 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); * see if they were valid. */ - memset(&cli, '\0', sizeof(struct cli_state)); + ZERO_STRUCT(cli); + if(cli_initialise(&cli) == False) { DEBUG(0,("domain_client_validate: unable to initialize client connection.\n")); return False; -- cgit From 66d5d73a5d75e88a77970f7b27687b8354ab2e80 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 25 Sep 1998 21:01:52 +0000 Subject: added rpcclient program (This used to be commit aa38f39d67fade4dfd7badb7a9b39c833a1dd1ca) --- source3/smbd/password.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1d90af3066..75934ec294 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -29,6 +29,7 @@ BOOL global_machine_pasword_needs_changing; /* users from session setup */ static pstring session_users=""; +extern pstring scope; extern pstring global_myname; extern fstring global_myworkgroup; @@ -929,6 +930,7 @@ struct cli_state *server_cryptkey(void) extern fstring local_machine; char *p; BOOL connected_ok = False; + struct nmb_name calling, called; if (!cli_initialise(&pw_cli)) return NULL; @@ -961,7 +963,11 @@ struct cli_state *server_cryptkey(void) return NULL; } - if (!cli_session_request(&pw_cli, desthost, 0x20, local_machine)) { + make_nmb_name(&calling, local_machine, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); + + if (!cli_session_request(&pw_cli, &calling, &called)) + { DEBUG(1,("%s rejected the session\n",desthost)); cli_shutdown(&pw_cli); return NULL; @@ -1124,6 +1130,7 @@ BOOL domain_client_validate( char *user, char *domain, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; + struct nmb_name calling, called; /* * Check that the requested domain is not our own machine name. @@ -1236,7 +1243,11 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); continue; } - if (!cli_session_request(&cli, remote_machine, 0x20, global_myname)) { + make_nmb_name(&calling, global_myname , 0x0 , scope); + make_nmb_name(&called , remote_machine, 0x20, scope); + + if (!cli_session_request(&pw_cli, &calling, &called)) + { DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); cli_shutdown(&cli); -- cgit From cf3a9741dc7427efb97eff09a3c197a906ce6767 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Sep 1998 21:43:48 +0000 Subject: Changes to test in configure if capabilities are enabled on a system. Changes to get Samba to compile cleanly with the IRIX compiler with the options : -fullwarn -woff 1209,1174 (the -woff options are to turn off warnings about unused function parameters and controlling loop expressions being constants). Split prototype generation as we hit a limit in IRIX nawk. Removed "." code in smbd/filename.c (yet again :-). Jeremy. (This used to be commit e0567433bd72aec17bf5a54cc292701095d25f09) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 75934ec294..f542dbe608 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -75,7 +75,7 @@ void generate_next_challenge(char *challenge) /******************************************************************* set the last challenge sent, usually from a password server ********************************************************************/ -BOOL set_challenge(char *challenge) +BOOL set_challenge(unsigned char *challenge) { memcpy(saved_challenge,challenge,8); challenge_sent = True; -- cgit From 9066025a8a4afe1f7f559c455d86fc023792ed17 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 29 Sep 1998 20:24:17 +0000 Subject: Got very strict about the differences and uses of uid_t, gid_t and vuid. Added sys_getgroups() to get around the int * return problem. Set correct datatypes for all uid, gid and vuid variables. Jeremy. (This used to be commit e570db46fc3a78e499523fd342e9a34cebb18998) --- source3/smbd/password.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f542dbe608..5a7e20e47e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -107,7 +107,7 @@ user_struct *get_valid_user_struct(uint16 vuid) return NULL; vuid -= VUID_OFFSET; if ((vuid >= (uint16)num_validated_users) || - (validated_users[vuid].uid == -1) || (validated_users[vuid].gid == -1)) + (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1)) return NULL; return &validated_users[vuid]; } @@ -121,17 +121,19 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; - vuser->uid = -1; - vuser->gid = -1; + vuser->uid = (uid_t)-1; + vuser->gid = (gid_t)-1; vuser->n_sids = 0; /* same number of igroups as groups */ vuser->n_groups = 0; - if (vuser->groups) free(vuser->groups); + if (vuser->groups) + free((char *)vuser->groups); - if (vuser->sids) free(vuser->sids); + if (vuser->sids) + free((char *)vuser->sids); vuser->sids = NULL; vuser->groups = NULL; @@ -153,11 +155,11 @@ char *validated_username(uint16 vuid) /**************************************************************************** Setup the groups a user belongs to. ****************************************************************************/ -int setup_groups(char *user, int uid, int gid, int *p_ngroups, GID_T **p_groups) +int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) { int i,ngroups; - GID_T *groups; - GID_T grp = 0; + gid_t grp = 0; + gid_t *groups = NULL; if (-1 == initgroups(user,gid)) { if (getuid() == 0) { @@ -170,15 +172,18 @@ int setup_groups(char *user, int uid, int gid, int *p_ngroups, GID_T **p_groups) return -1; } - ngroups = getgroups(0,&grp); - if (ngroups <= 0) ngroups = 32; + ngroups = sys_getgroups(0,&grp); + if (ngroups <= 0) + ngroups = 32; - groups = (GID_T *)malloc(sizeof(groups[0])*ngroups); + if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) { + DEBUG(0,("setup_groups malloc fail !\n")); + return -1; + } - ngroups = getgroups(ngroups,(gid_t *)groups); + ngroups = sys_getgroups(ngroups,groups); (*p_ngroups) = ngroups; - (*p_groups) = groups; DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) ); @@ -196,7 +201,7 @@ register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(int uid,int gid, char *unix_name, char *requested_name, BOOL guest) +uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -258,7 +263,7 @@ uint16 register_vuid(int uid,int gid, char *unix_name, char *requested_name, BOO &vuser->n_groups, &vuser->groups); - DEBUG(3,("uid %d registered to name %s\n",uid,unix_name)); + DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->real_name, "\0"); -- cgit From 40984f6b55212c710f6a7c7b940a785b2b607985 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 4 Oct 1998 12:00:40 +0000 Subject: - modified resolve_name() to take a name_type - cleaned up resolve_name() (split into separate functions for each resolver) - if can't find local master then use #1B name - support listing of foreign workgroups in /smb/ (This used to be commit a4e607c17d1119925c9d0e1d05e0fe81e9a2d1aa) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 5a7e20e47e..0ba4f1b7bf 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -945,7 +945,7 @@ struct cli_state *server_cryptkey(void) standard_sub_basic(desthost); strupper(desthost); - if(!resolve_name( desthost, &dest_ip)) { + if(!resolve_name( desthost, &dest_ip, 0x20)) { DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); continue; } @@ -1232,7 +1232,7 @@ machine %s in domain %s.\n", global_myname, global_myworkgroup )); standard_sub_basic(remote_machine); strupper(remote_machine); - if(!resolve_name( remote_machine, &dest_ip)) { + if(!resolve_name( remote_machine, &dest_ip, 0x20)) { DEBUG(1,("domain_client_validate: Can't resolve address for %s\n", remote_machine)); continue; } -- cgit From f8a3e2df1186de898866087536e56892b8e10ba7 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 6 Oct 1998 16:25:24 +0000 Subject: using wrong cli_state in "security = domain" call. (This used to be commit 1c08cc2466f7bf615a3508e028f0b65f120d2e5d) --- source3/smbd/password.c | 98 +++++++++++++++++++++++++------------------------ 1 file changed, 51 insertions(+), 47 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0ba4f1b7bf..49ad4a514f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -915,13 +915,12 @@ BOOL check_hosts_equiv(char *user) } -static struct cli_state pw_cli; - /**************************************************************************** return the client state structure ****************************************************************************/ struct cli_state *server_client(void) { + static struct cli_state pw_cli; return &pw_cli; } @@ -930,6 +929,7 @@ support for server level security ****************************************************************************/ struct cli_state *server_cryptkey(void) { + struct cli_state *cli; fstring desthost; struct in_addr dest_ip; extern fstring local_machine; @@ -937,7 +937,9 @@ struct cli_state *server_cryptkey(void) BOOL connected_ok = False; struct nmb_name calling, called; - if (!cli_initialise(&pw_cli)) + cli = server_client(); + + if (!cli_initialise(cli)) return NULL; p = lp_passwordserver(); @@ -955,7 +957,7 @@ struct cli_state *server_cryptkey(void) continue; } - if (cli_connect(&pw_cli, desthost, &dest_ip)) { + if (cli_connect(cli, desthost, &dest_ip)) { DEBUG(3,("connected to password server %s\n",desthost)); connected_ok = True; break; @@ -964,38 +966,38 @@ struct cli_state *server_cryptkey(void) if (!connected_ok) { DEBUG(0,("password server not available\n")); - cli_shutdown(&pw_cli); + cli_shutdown(cli); return NULL; } make_nmb_name(&calling, local_machine, 0x0 , scope); make_nmb_name(&called , desthost , 0x20, scope); - if (!cli_session_request(&pw_cli, &calling, &called)) + if (!cli_session_request(cli, &calling, &called)) { DEBUG(1,("%s rejected the session\n",desthost)); - cli_shutdown(&pw_cli); + cli_shutdown(cli); return NULL; } DEBUG(3,("got session\n")); - if (!cli_negprot(&pw_cli)) { + if (!cli_negprot(cli)) { DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(&pw_cli); + cli_shutdown(cli); return NULL; } - if (pw_cli.protocol < PROTOCOL_LANMAN2 || - !(pw_cli.sec_mode & 1)) { + if (cli->protocol < PROTOCOL_LANMAN2 || + !(cli->sec_mode & 1)) { DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(&pw_cli); + cli_shutdown(cli); return NULL; } DEBUG(3,("password server OK\n")); - return &pw_cli; + return cli; } /**************************************************************************** @@ -1005,11 +1007,13 @@ BOOL server_validate(char *user, char *domain, char *pass, int passlen, char *ntpass, int ntpasslen) { + struct cli_state *cli; extern fstring local_machine; static unsigned char badpass[24]; + cli = server_client(); - if (!pw_cli.initialised) { - DEBUG(1,("password server %s is not connected\n", pw_cli.desthost)); + if (!cli->initialised) { + DEBUG(1,("password server %s is not connected\n", cli->desthost)); return(False); } @@ -1030,17 +1034,17 @@ BOOL server_validate(char *user, char *domain, * need to detect this as some versions of NT4.x are broken. JRA. */ - if (cli_session_setup(&pw_cli, user, (char *)badpass, sizeof(badpass), + if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), (char *)badpass, sizeof(badpass), domain)) { - if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) == 0) { + if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { DEBUG(0,("server_validate: password server %s allows users as non-guest \ -with a bad password.\n", pw_cli.desthost)); +with a bad password.\n", cli->desthost)); DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - cli_ulogoff(&pw_cli); + cli_ulogoff(cli); return False; } - cli_ulogoff(&pw_cli); + cli_ulogoff(cli); } /* @@ -1048,15 +1052,15 @@ use this machine as the password server.\n")); * not guest enabled, we can try with the real password. */ - if (!cli_session_setup(&pw_cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", pw_cli.desthost)); + if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", cli->desthost)); return False; } /* if logged in as guest then reject */ - if ((SVAL(pw_cli.inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", pw_cli.desthost)); - cli_ulogoff(&pw_cli); + if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); + cli_ulogoff(cli); return(False); } @@ -1070,45 +1074,45 @@ use this machine as the password server.\n")); */ if (lp_net_wksta_user_logon()) { - DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); + DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli->desthost)); - if (!cli_send_tconX(&pw_cli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("password server %s refused IPC$ connect\n", pw_cli.desthost)); - cli_ulogoff(&pw_cli); + if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("password server %s refused IPC$ connect\n", cli->desthost)); + cli_ulogoff(cli); return False; } - if (!cli_NetWkstaUserLogon(&pw_cli,user,local_machine)) { - DEBUG(0,("password server %s failed NetWkstaUserLogon\n", pw_cli.desthost)); - cli_tdis(&pw_cli); - cli_ulogoff(&pw_cli); + if (!cli_NetWkstaUserLogon(cli,user,local_machine)) { + DEBUG(0,("password server %s failed NetWkstaUserLogon\n", cli->desthost)); + cli_tdis(cli); + cli_ulogoff(cli); return False; } - if (pw_cli.privilages == 0) { - DEBUG(0,("password server %s gave guest privilages\n", pw_cli.desthost)); - cli_tdis(&pw_cli); - cli_ulogoff(&pw_cli); + if (cli->privilages == 0) { + DEBUG(0,("password server %s gave guest privilages\n", cli->desthost)); + cli_tdis(cli); + cli_ulogoff(cli); return False; } - if (!strequal(pw_cli.eff_name, user)) { + if (!strequal(cli->eff_name, user)) { DEBUG(0,("password server %s gave different username %s\n", - pw_cli.desthost, - pw_cli.eff_name)); - cli_tdis(&pw_cli); - cli_ulogoff(&pw_cli); + cli->desthost, + cli->eff_name)); + cli_tdis(cli); + cli_ulogoff(cli); return False; } - cli_tdis(&pw_cli); + cli_tdis(cli); } else { - DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", pw_cli.desthost)); + DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli->desthost)); } - DEBUG(3,("password server %s accepted the password\n", pw_cli.desthost)); + DEBUG(3,("password server %s accepted the password\n", cli->desthost)); - cli_ulogoff(&pw_cli); + cli_ulogoff(cli); return(True); } @@ -1251,7 +1255,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); make_nmb_name(&calling, global_myname , 0x0 , scope); make_nmb_name(&called , remote_machine, 0x20, scope); - if (!cli_session_request(&pw_cli, &calling, &called)) + if (!cli_session_request(&cli, &calling, &called)) { DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); -- cgit From 99208208fa37483f2a97c004355628423e0c40eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 13 Oct 1998 14:14:09 +0000 Subject: use level 0 for DEBUG() of malformed password entry in smbpasswd (This used to be commit bff457b4a469c03977683c4521464c41f74db1ae) --- source3/smbd/password.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 49ad4a514f..b505da18fa 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -470,26 +470,26 @@ static BOOL pass_check_smb(char *user,char *password, struct passwd *pwd) } if (!pass) { - DEBUG(3,("Couldn't find user %s\n",user)); + DEBUG(1,("Couldn't find user %s\n",user)); return(False); } smb_pass = getsmbpwnam(user); if (!smb_pass) { - DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); + DEBUG(0,("Couldn't find user %s in smb_passwd file.\n", user)); return(False); } /* Quit if the account was disabled. */ if(smb_pass->acct_ctrl & ACB_DISABLED) { - DEBUG(3,("account for user %s was disabled.\n", user)); + DEBUG(0,("account for user %s was disabled.\n", user)); return(False); } /* Ensure the uid's match */ if (smb_pass->smb_userid != pass->pw_uid) { - DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); + DEBUG(0,("Error : UNIX and SMB uids in password files do not match !\n")); return(False); } -- cgit From 935dc98f6670ba630bd2086ef9eddcc94a0562e2 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 14 Oct 1998 06:29:20 +0000 Subject: dce/rpc (This used to be commit 69f5f9f88935de1f63ffc9aa19c0629b395e66e6) --- source3/smbd/password.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b505da18fa..49ad4a514f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -470,26 +470,26 @@ static BOOL pass_check_smb(char *user,char *password, struct passwd *pwd) } if (!pass) { - DEBUG(1,("Couldn't find user %s\n",user)); + DEBUG(3,("Couldn't find user %s\n",user)); return(False); } smb_pass = getsmbpwnam(user); if (!smb_pass) { - DEBUG(0,("Couldn't find user %s in smb_passwd file.\n", user)); + DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); return(False); } /* Quit if the account was disabled. */ if(smb_pass->acct_ctrl & ACB_DISABLED) { - DEBUG(0,("account for user %s was disabled.\n", user)); + DEBUG(3,("account for user %s was disabled.\n", user)); return(False); } /* Ensure the uid's match */ if (smb_pass->smb_userid != pass->pw_uid) { - DEBUG(0,("Error : UNIX and SMB uids in password files do not match !\n")); + DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); return(False); } -- cgit From fc7d3e4caa7650c02ef36fff83b64b06050f66b1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Oct 1998 00:55:17 +0000 Subject: config: Fix crypt prototype on RedHat Linux. include/includes.h: Fix crypt prototype on RedHat Linux. smbd/fileio.c: Fix mmap bug found by WinCE client. smbd/ipc.c: Fix WinCE wierdness with pipes being opened as \server\pipe\lanman smbd/password.c: Fix encrypted null passwords. Jeremy. (This used to be commit 475992730c0ecbf31c09b3518df2f0354cec61da) --- source3/smbd/password.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 49ad4a514f..761313b688 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -379,6 +379,7 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ + BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar lm_pass[24], uchar nt_pass[24]) { @@ -386,6 +387,9 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, if (!lm_pass || !smb_pass) return(False); + DEBUG(4,("Checking SMB password for user %s\n", + smb_pass->smb_name)); + if(smb_pass->acct_ctrl & ACB_DISABLED) { DEBUG(3,("account for user %s was disabled.\n", smb_pass->smb_name)); @@ -397,9 +401,6 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, return False; } - DEBUG(4,("Checking SMB password for user %s\n", - smb_pass->smb_name)); - if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) { /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). @@ -493,6 +494,11 @@ static BOOL pass_check_smb(char *user,char *password, struct passwd *pwd) return(False); } + if(password[0] == '\0' && smb_pass->acct_ctrl & ACB_PWNOTREQ && lp_null_passwords()) { + DEBUG(3,("account for user %s has no password and null passwords are allowed.\n", smb_pass->smb_name)); + return(True); + } + if (smb_password_ok(smb_pass, (unsigned char *)password, (uchar *)password)) { @@ -510,7 +516,7 @@ return True if the password is correct, False otherwise ****************************************************************************/ BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) { - if (pwlen == 24) { + if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { /* if it is 24 bytes long then assume it is an encrypted password */ return pass_check_smb(user, password, pwd); -- cgit From c404bb775414139a4b07a73f79cf069a083acb26 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Oct 1998 23:51:07 +0000 Subject: rpcclient interactive login (with trust account changing if you are root) cli_session_setup handles null sessions correctly (This used to be commit 60c0f22a4e84703467006dfe1971384a6294a9aa) --- source3/smbd/password.c | 25 ++----------------------- 1 file changed, 2 insertions(+), 23 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 761313b688..45d4d72863 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -24,8 +24,6 @@ extern int DEBUGLEVEL; extern int Protocol; -BOOL global_machine_pasword_needs_changing; - /* users from session setup */ static pstring session_users=""; @@ -1136,7 +1134,6 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; unsigned char trust_passwd[16]; - time_t lct; fstring remote_machine; char *p; struct in_addr dest_ip; @@ -1193,29 +1190,11 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password. */ - if(!trust_password_lock( global_myworkgroup, global_myname, False)) { - DEBUG(0,("domain_client_validate: unable to open the machine account password file for \ -machine %s in domain %s.\n", global_myname, global_myworkgroup )); - return False; - } - - if(get_trust_account_password( trust_passwd, &lct) == False) { - DEBUG(0,("domain_client_validate: unable to read the machine account password for \ -machine %s in domain %s.\n", global_myname, global_myworkgroup )); - trust_password_unlock(); + if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) + { return False; } - trust_password_unlock(); - - /* - * Here we check the last change time to see if the machine - * password needs changing. JRA. - */ - - if(time(NULL) > lct + lp_machine_password_timeout()) - global_machine_pasword_needs_changing = True; - /* * At this point, smb_apasswd points to the lanman response to * the challenge in local_challenge, and smb_ntpasswd points to -- cgit From 5cb99177aff3522427d520d5f5159989f6d72265 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Oct 1998 20:13:26 +0000 Subject: setup_groups() - code clarification. no functional change. (This used to be commit dae7c5ea9a139552e1722357172fa1ad0c4a7143) --- source3/smbd/password.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 45d4d72863..3ab963bfa8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -157,14 +157,16 @@ int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_gro { int i,ngroups; gid_t grp = 0; - gid_t *groups = NULL; + gid_t *groups = NULL; - if (-1 == initgroups(user,gid)) { - if (getuid() == 0) { + if (-1 == initgroups(user,gid)) + { + if (getuid() == 0) + { DEBUG(0,("Unable to initgroups!\n")); - if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000) { - DEBUG(0,("This is probably a problem with the account %s\n", - user)); + if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000) + { + DEBUG(0,("This is probably a problem with the account %s\n", user)); } } return -1; @@ -172,20 +174,24 @@ int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_gro ngroups = sys_getgroups(0,&grp); if (ngroups <= 0) - ngroups = 32; + { + ngroups = 32; + } - if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) { - DEBUG(0,("setup_groups malloc fail !\n")); - return -1; - } + if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) + { + DEBUG(0,("setup_groups malloc fail !\n")); + return -1; + } - ngroups = sys_getgroups(ngroups,groups); + ngroups = sys_getgroups(ngroups,groups); (*p_ngroups) = ngroups; (*p_groups) = groups; DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) ); - for (i = 0; i < ngroups; i++ ) { + for (i = 0; i < ngroups; i++ ) + { DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) ); } DEBUG( 3, ( "\n" ) ); -- cgit From 3637ad5f2b0e5716aceaada0eed47f926c95520f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Oct 1998 20:18:46 +0000 Subject: cli_nt_session_open() encrypt arg removed (This used to be commit 63def717992695ed4a4933c2605abe26086fb8c7) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3ab963bfa8..ac8210abf8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1313,7 +1313,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); * Now start the NT Domain stuff :-). */ - if(cli_nt_session_open(&cli, PIPE_NETLOGON, False) == False) { + if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) { DEBUG(0,("domain_client_validate: unable to open the domain client session to \ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); cli_nt_session_close(&cli); -- cgit From 97f0c9d55014db221fdceaaf07318ae9df9688a1 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Oct 1998 21:36:19 +0000 Subject: made pass_check_smb() available for dce/rpc use. (This used to be commit 95e8a910c5d9ba0ef57669fb1256eaa932e0bb09) --- source3/smbd/password.c | 59 ++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 25 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ac8210abf8..4df359f46c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -449,39 +449,38 @@ check if a username/password is OK assuming the password is a 24 byte SMB hash return True if the password is correct, False otherwise ****************************************************************************/ -static BOOL pass_check_smb(char *user,char *password, struct passwd *pwd) +BOOL pass_check_smb(char *user, char *domain, + char *challenge, char *lm_pwd, char *nt_pwd, + struct passwd *pwd) { struct passwd *pass; - uchar challenge[8]; struct smb_passwd *smb_pass; - BOOL challenge_done; - if (!password) { + if (!lm_pwd || !nt_pwd) + { return(False); } - challenge_done = last_challenge(challenge); - - if (!challenge_done) { - DEBUG(0,("Error: challenge not done for user=%s\n", user)); - return False; - } - - if (pwd && !user) { + if (pwd != NULL && user == NULL) + { pass = (struct passwd *) pwd; user = pass->pw_name; - } else { + } + else + { pass = Get_Pwnam(user,True); } - if (!pass) { + if (pass != NULL) + { DEBUG(3,("Couldn't find user %s\n",user)); return(False); } smb_pass = getsmbpwnam(user); - if (!smb_pass) { + if (smb_pass != NULL) + { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); return(False); } @@ -493,19 +492,20 @@ static BOOL pass_check_smb(char *user,char *password, struct passwd *pwd) } /* Ensure the uid's match */ - if (smb_pass->smb_userid != pass->pw_uid) { + if (smb_pass->smb_userid != pass->pw_uid) + { DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); return(False); } - if(password[0] == '\0' && smb_pass->acct_ctrl & ACB_PWNOTREQ && lp_null_passwords()) { + if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords()) + { DEBUG(3,("account for user %s has no password and null passwords are allowed.\n", smb_pass->smb_name)); return(True); } - if (smb_password_ok(smb_pass, - (unsigned char *)password, - (uchar *)password)) { + if (smb_password_ok(smb_pass, (uchar *)lm_pwd, (uchar *)nt_pwd)) + { return(True); } @@ -518,12 +518,21 @@ check if a username/password pair is OK either via the system password database or the encrypted SMB password database return True if the password is correct, False otherwise ****************************************************************************/ -BOOL password_ok(char *user,char *password, int pwlen, struct passwd *pwd) +BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) { - if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { - /* if it is 24 bytes long then assume it is an encrypted - password */ - return pass_check_smb(user, password, pwd); + if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) + { + /* if 24 bytes long assume it is an encrypted password */ + uchar challenge[8]; + + if (!last_challenge(challenge)) + { + DEBUG(0,("Error: challenge not done for user=%s\n", user)); + return False; + } + + return pass_check_smb(user, global_myworkgroup, + challenge, password, password, pwd); } return pass_check(user, password, pwlen, pwd, -- cgit From b6993a89af080d4d5c176ae9d539ff553f69c247 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Oct 1998 21:41:42 +0000 Subject: !pass -> pass != NULL is wrong: !pass -> pass == NULL is correct. oops. (This used to be commit 866e1018180a70ff2ffa39e6a5ce5f187eca2764) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4df359f46c..1c9eb19759 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -471,7 +471,7 @@ BOOL pass_check_smb(char *user, char *domain, pass = Get_Pwnam(user,True); } - if (pass != NULL) + if (pass == NULL) { DEBUG(3,("Couldn't find user %s\n",user)); return(False); @@ -479,7 +479,7 @@ BOOL pass_check_smb(char *user, char *domain, smb_pass = getsmbpwnam(user); - if (smb_pass != NULL) + if (smb_pass == NULL) { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); return(False); -- cgit From 01de6030843f5f402dee8bf72f564a91ae8437ca Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 19 Oct 1998 17:32:10 +0000 Subject: - dce/rpc code - removed debug info in struni2 and unistr2 (security risk) - rpc_pipe function was getting pointer to data then calling realloc *dur* - password check function, the start of "credential checking", user, wks, domain, pass as the credentials (not just user,pass which is incorrect in a domain context) - cli_write needs to return ssize_t not size_t, because total can be -1 if the write fails. - fixed signed / unsigned warnings (how come i don't get those any more when i compile with gcc???) - nt password change added in smbd. yes, jeremy, i verified that the SMBtrans2 version still works. (This used to be commit fcfb40d2b0fc565ee4f66b3a3761c246366a2ef3) --- source3/smbd/password.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1c9eb19759..eac8c9cd65 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -383,8 +383,7 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ - -BOOL smb_password_ok(struct smb_passwd *smb_pass, +BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], uchar lm_pass[24], uchar nt_pass[24]) { uchar challenge[8]; @@ -400,9 +399,19 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, return(False); } - if (!last_challenge(challenge)) { - DEBUG(1,("no challenge done - password failed\n")); - return False; + if (chal == NULL) + { + DEBUG(5,("use last SMBnegprot challenge\n")); + if (!last_challenge(challenge)) + { + DEBUG(1,("no challenge done - password failed\n")); + return False; + } + } + else + { + DEBUG(5,("challenge received\n")); + memcpy(challenge, chal, 8); } if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) { @@ -450,7 +459,7 @@ SMB hash return True if the password is correct, False otherwise ****************************************************************************/ BOOL pass_check_smb(char *user, char *domain, - char *challenge, char *lm_pwd, char *nt_pwd, + uchar *chal, char *lm_pwd, char *nt_pwd, struct passwd *pwd) { struct passwd *pass; @@ -504,7 +513,7 @@ BOOL pass_check_smb(char *user, char *domain, return(True); } - if (smb_password_ok(smb_pass, (uchar *)lm_pwd, (uchar *)nt_pwd)) + if (smb_password_ok(smb_pass, chal, (uchar *)lm_pwd, (uchar *)nt_pwd)) { return(True); } -- cgit From 6e3af45afe237790f1d7cd94ab2b22e1ca772157 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 21 Oct 1998 16:58:34 +0000 Subject: Fixed mainly signed/unsigned issues found by SGI cc in -fullwarn mode. smbd/chgpasswd.c: Fixed (my) stupid bug where I was returning stack based variables. Doh ! smbd/trans2.c: Allows SETFILEINFO as well as QFILEINFO on directory handles. Jeremy. (This used to be commit 0b44d27d0b5cc3948a6c2d78370ccddf1a84cd80) --- source3/smbd/password.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index eac8c9cd65..95560df66b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -458,8 +458,9 @@ check if a username/password is OK assuming the password is a 24 byte SMB hash return True if the password is correct, False otherwise ****************************************************************************/ + BOOL pass_check_smb(char *user, char *domain, - uchar *chal, char *lm_pwd, char *nt_pwd, + uchar *chal, uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd) { struct passwd *pass; @@ -513,7 +514,7 @@ BOOL pass_check_smb(char *user, char *domain, return(True); } - if (smb_password_ok(smb_pass, chal, (uchar *)lm_pwd, (uchar *)nt_pwd)) + if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd)) { return(True); } @@ -541,7 +542,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) } return pass_check_smb(user, global_myworkgroup, - challenge, password, password, pwd); + challenge, (uchar *)password, (uchar *)password, pwd); } return pass_check(user, password, pwlen, pwd, -- cgit From 548b417d404a2653ebb5918b0c169ccdfafe856f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 7 Nov 1998 05:32:37 +0000 Subject: codepages/codepage_def.936: Updated comment. param/loadparm.c: Removed "networkstation user login", "domain controller", and "domain sid" parameters. passdb/passdb.c: Removed "networkstation user login" code and changed bug test code to only check once for a bad password server. This will stop the complaints of many "bad login" audit records in NT PDC logs. utils/smbpasswd.c: Removed check for "domain controller". Jeremy. (This used to be commit d6e6e936b5dd90dd8fc38d9404efbe5c546c15e5) --- source3/smbd/password.c | 162 ++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 89 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 95560df66b..d49ea7c562 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1036,114 +1036,98 @@ BOOL server_validate(char *user, char *domain, char *pass, int passlen, char *ntpass, int ntpasslen) { - struct cli_state *cli; - extern fstring local_machine; - static unsigned char badpass[24]; - cli = server_client(); + struct cli_state *cli; + extern fstring local_machine; + static unsigned char badpass[24]; + static BOOL tested_password_server = False; + static BOOL bad_password_server = False; - if (!cli->initialised) { - DEBUG(1,("password server %s is not connected\n", cli->desthost)); - return(False); - } + cli = server_client(); - if(badpass[0] == 0) { - memset(badpass, 0x1f, sizeof(badpass)); - } + if (!cli->initialised) { + DEBUG(1,("password server %s is not connected\n", cli->desthost)); + return(False); + } - if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { - /* Very unlikely, our random bad password is the same as the users - password. */ - memset(badpass, badpass[0]+1, sizeof(badpass)); - } + if(badpass[0] == 0) + memset(badpass, 0x1f, sizeof(badpass)); - /* - * Attempt a session setup with a totally incorrect password. - * If this succeeds with the guest bit *NOT* set then the password - * server is broken and is not correctly setting the guest bit. We - * need to detect this as some versions of NT4.x are broken. JRA. - */ + if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { + /* + * Very unlikely, our random bad password is the same as the users + * password. */ + memset(badpass, badpass[0]+1, sizeof(badpass)); + } - if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), - (char *)badpass, sizeof(badpass), domain)) { - if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { - DEBUG(0,("server_validate: password server %s allows users as non-guest \ -with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ -use this machine as the password server.\n")); - cli_ulogoff(cli); - return False; - } - cli_ulogoff(cli); - } + /* + * Attempt a session setup with a totally incorrect password. + * If this succeeds with the guest bit *NOT* set then the password + * server is broken and is not correctly setting the guest bit. We + * need to detect this as some versions of NT4.x are broken. JRA. + */ - /* - * Now we know the password server will correctly set the guest bit, or is - * not guest enabled, we can try with the real password. - */ + if(!tested_password_server) { + if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), + (char *)badpass, sizeof(badpass), domain)) { - if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli->desthost)); - return False; - } + /* + * We connected to the password server so we + * can say we've tested it. + */ + tested_password_server = True; - /* if logged in as guest then reject */ - if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); - cli_ulogoff(cli); - return(False); - } + if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { + DEBUG(0,("server_validate: password server %s allows users as non-guest \ +with a bad password.\n", cli->desthost)); + DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ +use this machine as the password server.\n")); + cli_ulogoff(cli); /* - * This patch from Rob Nielsen makes doing - * the NetWksaUserLogon a dynamic, rather than compile-time - * parameter, defaulting to on. This is somewhat dangerous - * as it allows people to turn off this neccessary check, - * but so many people have had problems with this that I - * think it is a neccessary change. JRA. + * Password server has the bug. */ + bad_password_server = True; + return False; + } + cli_ulogoff(cli); + } + } else { - if (lp_net_wksta_user_logon()) { - DEBUG(3,("trying NetWkstaUserLogon with password server %s\n", cli->desthost)); + /* + * We have already tested the password server. + * Fail immediately if it has the bug. + */ - if (!cli_send_tconX(cli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("password server %s refused IPC$ connect\n", cli->desthost)); - cli_ulogoff(cli); - return False; - } + if(bad_password_server) { + DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ +with a bad password.\n", cli->desthost)); + DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ +use this machine as the password server.\n")); + return False; + } + } - if (!cli_NetWkstaUserLogon(cli,user,local_machine)) { - DEBUG(0,("password server %s failed NetWkstaUserLogon\n", cli->desthost)); - cli_tdis(cli); - cli_ulogoff(cli); - return False; - } + /* + * Now we know the password server will correctly set the guest bit, or is + * not guest enabled, we can try with the real password. + */ - if (cli->privilages == 0) { - DEBUG(0,("password server %s gave guest privilages\n", cli->desthost)); - cli_tdis(cli); - cli_ulogoff(cli); - return False; - } + if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", cli->desthost)); + return False; + } - if (!strequal(cli->eff_name, user)) { - DEBUG(0,("password server %s gave different username %s\n", - cli->desthost, - cli->eff_name)); - cli_tdis(cli); - cli_ulogoff(cli); - return False; - } - cli_tdis(cli); - } - else { - DEBUG(3,("skipping NetWkstaUserLogon with password server %s\n", cli->desthost)); - } + /* if logged in as guest then reject */ + if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); + cli_ulogoff(cli); + return(False); + } - DEBUG(3,("password server %s accepted the password\n", cli->desthost)); - cli_ulogoff(cli); + cli_ulogoff(cli); - return(True); + return(True); } /*********************************************************************** -- cgit From 8c62b28e0ef1e012ebb0713701916d82ffc7661e Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 9 Nov 1998 03:45:49 +0000 Subject: converted smbclient to use clientgen.c rather than clientutil.c I did this when I saw yet another bug report complaining about smbclient intermittently missing files. Rather than applying more patches to smbclient it was better to move to the more robust clientgen.c code. The conversion wasn't perfect, I probably lost some features of smbclient while doing it, but at least smbclient should be consistent now. It if fails it should _always_ fail rather than giving people the false impression of a reliable utility. the tar stuff seems to work, but hasn't had much testing as I never use it myself. I'm sure someone will find bugs in my conversion of smbtar.c. It was quite tricky as it did a lot of its own SMB calls. It now uses clientgen.c exclusively. smbclient is still quite messy, but at least it doesn't build its own SMB packets. I haven't touched smbmount as I never use it. Mike, do you want to convert smbmount to use clientgen.c? (This used to be commit e14ca7765ace1b721dad8eca4a527a4e4a8f1ab8) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index d49ea7c562..fb5acf156f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1037,7 +1037,6 @@ BOOL server_validate(char *user, char *domain, char *ntpass, int ntpasslen) { struct cli_state *cli; - extern fstring local_machine; static unsigned char badpass[24]; static BOOL tested_password_server = False; static BOOL bad_password_server = False; -- cgit From 74d539f5573a3ed3ff1b96c54752a389da4c3e14 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 17 Nov 1998 16:19:04 +0000 Subject: - group database API. oops and oh dear, the threat has been carried out: the pre-alpha "domain group" etc parameters have disappeared. - interactive debug detection - re-added mem_man (andrew's memory management, detects memory corruption) - american spellings of "initialise" replaced with english spelling of "initialise". - started on "lookup_name()" and "lookup_sid()" functions. proper ones. - moved lots of functions around. created some modules of commonly used code. e.g the password file locking code, which is used in groupfile.c and aliasfile.c and smbpass.c - moved RID_TYPE_MASK up another bit. this is really unfortunate, but there is no other "fast" way to identify users from groups from aliases. i do not believe that this code saves us anything (the multipliers) and puts us at a disadvantage (reduces the useable rid space). the designers of NT aren't silly: if they can get away with a user- interface-speed LsaLookupNames / LsaLookupSids, then so can we. i spoke with isaac at the cifs conference, the only time for example that they do a security context check is on file create. certainly not on individual file reads / writes, which would drastically hit their performance and ours, too. - renamed myworkgroup to global_sam_name, amongst other things, when used in the rpc code. there is also a global_member_name, as we are always responsible for a SAM database, the scope of which is limited by the role of the machine (e.g if a member of a workgroup, your SAM is for _local_ logins only, and its name is the name of your server. you even still have a SID. see LsaQueryInfoPolicy, levels 3 and 5). - updated functionality of groupname.c to be able to cope with names like DOMAIN\group and SERVER\alias. used this code to be able to do aliases as well as groups. this code may actually be better off being used in username mapping, too. - created a connect to serverlist function in clientgen.c and used it in password.c - initialisation in server.c depends on the role of the server. well, it does now. - rpctorture. smbtorture. EXERCISE EXTREME CAUTION. (This used to be commit 0d21e1e6090b933f396c764af535ca3388a562db) --- source3/smbd/password.c | 114 ++++-------------------------------------------- 1 file changed, 8 insertions(+), 106 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fb5acf156f..0c8eb124ff 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -153,7 +153,7 @@ char *validated_username(uint16 vuid) /**************************************************************************** Setup the groups a user belongs to. ****************************************************************************/ -int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) +int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) { int i,ngroups; gid_t grp = 0; @@ -180,7 +180,7 @@ int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_gro if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) { - DEBUG(0,("setup_groups malloc fail !\n")); + DEBUG(0,("get_unixgroups malloc fail !\n")); return -1; } @@ -263,7 +263,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(unix_name,uid,gid, + get_unixgroups(unix_name,uid,gid, &vuser->n_groups, &vuser->groups); @@ -1142,15 +1142,10 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; unsigned char trust_passwd[16]; - fstring remote_machine; - char *p; - struct in_addr dest_ip; NET_ID_INFO_CTR ctr; NET_USER_INFO_3 info3; struct cli_state cli; uint32 smb_uid_low; - BOOL connected_ok = False; - struct nmb_name calling, called; /* * Check that the requested domain is not our own machine name. @@ -1211,102 +1206,9 @@ BOOL domain_client_validate( char *user, char *domain, * see if they were valid. */ - ZERO_STRUCT(cli); - - if(cli_initialise(&cli) == False) { - DEBUG(0,("domain_client_validate: unable to initialize client connection.\n")); - return False; - } - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - p = lp_passwordserver(); - while(p && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { - - standard_sub_basic(remote_machine); - strupper(remote_machine); - - if(!resolve_name( remote_machine, &dest_ip, 0x20)) { - DEBUG(1,("domain_client_validate: Can't resolve address for %s\n", remote_machine)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("domain_client_validate: Password server loop - not using password server %s\n",remote_machine)); - continue; - } - - if (!cli_connect(&cli, remote_machine, &dest_ip)) { - DEBUG(0,("domain_client_validate: unable to connect to SMB server on \ -machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli) )); - continue; - } - - make_nmb_name(&calling, global_myname , 0x0 , scope); - make_nmb_name(&called , remote_machine, 0x20, scope); - - if (!cli_session_request(&cli, &calling, &called)) + if (!cli_connect_serverlist(&cli, lp_passwordserver())) { - DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ -Error was : %s.\n", remote_machine, cli_errstr(&cli) )); - cli_shutdown(&cli); - continue; - } - - cli.protocol = PROTOCOL_NT1; - - if (!cli_negprot(&cli)) { - DEBUG(0,("domain_client_validate: machine %s rejected the negotiate protocol. \ -Error was : %s.\n", remote_machine, cli_errstr(&cli) )); - cli_shutdown(&cli); - continue; - } - - if (cli.protocol != PROTOCOL_NT1) { - DEBUG(0,("domain_client_validate: machine %s didn't negotiate NT protocol.\n", - remote_machine)); - cli_shutdown(&cli); - continue; - } - - /* - * Do an anonymous session setup. - */ - - if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) { - DEBUG(0,("domain_client_validate: machine %s rejected the session setup. \ -Error was : %s.\n", remote_machine, cli_errstr(&cli) )); - cli_shutdown(&cli); - continue; - } - - if (!(cli.sec_mode & 1)) { - DEBUG(1,("domain_client_validate: machine %s isn't in user level security mode\n", - remote_machine)); - cli_shutdown(&cli); - continue; - } - - if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("domain_client_validate: machine %s rejected the tconX on the IPC$ share. \ -Error was : %s.\n", remote_machine, cli_errstr(&cli) )); - cli_shutdown(&cli); - continue; - } - - /* - * We have an anonymous connection to IPC$. - */ - connected_ok = True; - break; - } - - if (!connected_ok) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); - cli_shutdown(&cli); return False; } @@ -1317,7 +1219,7 @@ Error was : %s.\n", remote_machine, cli_errstr(&cli) )); if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) { DEBUG(0,("domain_client_validate: unable to open the domain client session to \ -machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); +machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); @@ -1326,7 +1228,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); if(cli_nt_setup_creds(&cli, trust_passwd) == False) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ -%s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); +%s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); @@ -1341,7 +1243,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), &ctr, &info3) == False) { DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); +%s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); @@ -1361,7 +1263,7 @@ machine %s. Error was : %s.\n", remote_machine, cli_errstr(&cli))); if(cli_nt_logoff(&cli, &ctr) == False) { DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); +%s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); -- cgit From 768761820e8d7481c586c4e0ab4ac7cb36d18c4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 17 Nov 1998 20:50:07 +0000 Subject: Added the same open()/fopen()/creat()/mmap() -> sys_XXX calls. Tidied up some of the mess (no other word for it). Still doesn't compile cleanly. There are calls with incorrect parameters that don't seem to be doing the right thing. This code still needs surgery :-(. Jeremy. (This used to be commit 18ff93a9abbf68ee8c59c0af3e57c63e4a015dac) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0c8eb124ff..9011b9b95e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -813,7 +813,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) int plus_allowed = 1; char *file_host; char *file_user; - FILE *fp = fopen(equiv_file, "r"); + FILE *fp = sys_fopen(equiv_file, "r"); DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); if (! fp) return False; while(fgets(buf, sizeof(buf), fp)) -- cgit From a97baa50fdbf951cf3568b7068a7194f22642d52 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 21 Nov 1998 00:16:28 +0000 Subject: smbd/password.c: Added *SMBSERVER fix is name is too long. web/swat.c: Changed '?' to help. Jeremy. (This used to be commit 631913ea856926a77304692c74a1bd27faead179) --- source3/smbd/password.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9011b9b95e..683303ff87 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1000,7 +1000,15 @@ struct cli_state *server_cryptkey(void) } make_nmb_name(&calling, local_machine, 0x0 , scope); - make_nmb_name(&called , desthost , 0x20, scope); + + if(strlen(desthost) > 15) + { + DEBUG(1,("server_cryptkey: %s is too long for a password server NetBIOS \ +name, using *SMBSERVER for the connection.\n", desthost )); + make_nmb_name(&called , "*SMBSERVER", 0x20, scope); + } + else + make_nmb_name(&called , desthost , 0x20, scope); if (!cli_session_request(cli, &calling, &called)) { -- cgit From 091a92e9962a9526dd355b8f6c2e57b0fba167ab Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 21 Nov 1998 01:28:15 +0000 Subject: try to use *SMBSERVER to connect to password server if the first session_request fails. (This used to be commit ab2370e7ac770f1e32b8d726ab955457fcc8c2d7) --- source3/smbd/password.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 683303ff87..8b73ff4518 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1000,21 +1000,19 @@ struct cli_state *server_cryptkey(void) } make_nmb_name(&calling, local_machine, 0x0 , scope); + make_nmb_name(&called , desthost , 0x20, scope); - if(strlen(desthost) > 15) - { - DEBUG(1,("server_cryptkey: %s is too long for a password server NetBIOS \ -name, using *SMBSERVER for the connection.\n", desthost )); - make_nmb_name(&called , "*SMBSERVER", 0x20, scope); - } - else - make_nmb_name(&called , desthost , 0x20, scope); - - if (!cli_session_request(cli, &calling, &called)) - { - DEBUG(1,("%s rejected the session\n",desthost)); + if (!cli_session_request(cli, &calling, &called)) { + /* try with *SMBSERVER if the first name fails */ cli_shutdown(cli); - return NULL; + make_nmb_name(&called , "*SMBSERVER", 0x20, scope); + if (!cli_initialise(cli) || + !cli_connect(cli, desthost, &dest_ip) || + !cli_session_request(cli, &calling, &called)) { + DEBUG(1,("%s rejected the session\n",desthost)); + cli_shutdown(cli); + return NULL; + } } DEBUG(3,("got session\n")); -- cgit From 30038de4623bc827ee8019c569faf00583d1fe58 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 29 Nov 1998 20:03:33 +0000 Subject: weekend work. user / group database API. - split sam_passwd and smb_passwd into separate higher-order function tables - renamed struct smb_passwd's "smb_user" to "unix_user". added "nt_user" plus user_rid, and added a "wrap" function in both sam_passwd and smb_passwd password databases to fill in the blank entries that are not obtained from whatever password database API instance is being used. NOTE: whenever a struct smb_passwd or struct sam_passwd is used, it MUST be initialised with pwdb_sam_init() or pwd_smb_init(), see chgpasswd.c for the only example outside of the password database APIs i could find. - added query_useraliases code to rpcclient. - dealt with some nasty interdependencies involving non-smbd programs and the password database API. this is still not satisfactorily resolved completelely, but it's the best i can do for now. - #ifdef'd out some password database options so that people don't mistakenly set them unless they recompile to _use_ those options. lots of debugging done, it's still not finished. the unix/NT uid/gid and user-rid/group-rid issues are better, but not perfect. the "BUILTIN" domain is still missing: users cannot be added to "BUILTIN" groups yet, as we only have an "alias" db API and a "group" db API but not "builtin-alias" db API... (This used to be commit 5d5d7e4de7d1514ab87b07ede629de8aa00519a1) --- source3/smbd/password.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8b73ff4518..ed47e6d3e5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -391,11 +391,11 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], if (!lm_pass || !smb_pass) return(False); DEBUG(4,("Checking SMB password for user %s\n", - smb_pass->smb_name)); + smb_pass->unix_name)); if(smb_pass->acct_ctrl & ACB_DISABLED) { DEBUG(3,("account for user %s was disabled.\n", - smb_pass->smb_name)); + smb_pass->unix_name)); return(False); } @@ -436,7 +436,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], if((smb_pass->smb_passwd == NULL) && (smb_pass->acct_ctrl & ACB_PWNOTREQ)) { DEBUG(4,("no password required for user %s\n", - smb_pass->smb_name)); + smb_pass->unix_name)); return True; } @@ -502,7 +502,7 @@ BOOL pass_check_smb(char *user, char *domain, } /* Ensure the uid's match */ - if (smb_pass->smb_userid != pass->pw_uid) + if (smb_pass->unix_uid != pass->pw_uid) { DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); return(False); @@ -510,7 +510,7 @@ BOOL pass_check_smb(char *user, char *domain, if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords()) { - DEBUG(3,("account for user %s has no password and null passwords are allowed.\n", smb_pass->smb_name)); + DEBUG(3,("account for user %s has no password and null passwords are allowed.\n", smb_pass->unix_name)); return(True); } @@ -587,7 +587,7 @@ validate a group username entry. Return the username or NULL ****************************************************************************/ static char *validate_group(char *group,char *password,int pwlen,int snum) { -#ifdef HAVE_NETGROUP +#if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT) { char *host, *user, *domain; setnetgrent(group); -- cgit From f3787515d67b80a91786cfdd2fd2fb5972b4b094 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 3 Dec 1998 17:41:14 +0000 Subject: moved get_unixgroups it will be needed by the unix instance of the group DB API (This used to be commit ef58e48bc9af338ed6c734205d4faf82371284ac) --- source3/smbd/password.c | 49 ------------------------------------------------- 1 file changed, 49 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ed47e6d3e5..8718e75c3b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -150,55 +150,6 @@ char *validated_username(uint16 vuid) } -/**************************************************************************** -Setup the groups a user belongs to. -****************************************************************************/ -int get_unixgroups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) -{ - int i,ngroups; - gid_t grp = 0; - gid_t *groups = NULL; - - if (-1 == initgroups(user,gid)) - { - if (getuid() == 0) - { - DEBUG(0,("Unable to initgroups!\n")); - if (gid < 0 || gid > 16000 || uid < 0 || uid > 16000) - { - DEBUG(0,("This is probably a problem with the account %s\n", user)); - } - } - return -1; - } - - ngroups = sys_getgroups(0,&grp); - if (ngroups <= 0) - { - ngroups = 32; - } - - if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) - { - DEBUG(0,("get_unixgroups malloc fail !\n")); - return -1; - } - - ngroups = sys_getgroups(ngroups,groups); - - (*p_ngroups) = ngroups; - (*p_groups) = groups; - - DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) ); - for (i = 0; i < ngroups; i++ ) - { - DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) ); - } - DEBUG( 3, ( "\n" ) ); - - return 0; -} - /**************************************************************************** register a uid/name pair as being valid and that a valid password -- cgit From 9c848ec329a6ce86cffb2304746590116d9292f0 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 7 Dec 1998 20:23:41 +0000 Subject: removed nt_pipe_fnum from struct cli_state. need to be able to call LsaLookupSids etc from within SamrQueryAliasMembers, for example. fnum is now a parameter to client functions. thanks to mike black for starting the ball rolling. (This used to be commit bee8f7fa6b0f7f995f71303f4e14a4aaed0c2437) --- source3/smbd/password.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8718e75c3b..726d93e404 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1095,6 +1095,7 @@ BOOL domain_client_validate( char *user, char *domain, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) { + uint16 nt_pipe_fnum; unsigned char local_challenge[8]; unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; @@ -1174,19 +1175,19 @@ BOOL domain_client_validate( char *user, char *domain, * Now start the NT Domain stuff :-). */ - if(cli_nt_session_open(&cli, PIPE_NETLOGON) == False) { + if(cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum) == False) { DEBUG(0,("domain_client_validate: unable to open the domain client session to \ machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli); + cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); return False; } - if(cli_nt_setup_creds(&cli, trust_passwd) == False) { + if(cli_nt_setup_creds(&cli, nt_pipe_fnum, trust_passwd) == False) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli); + cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); return False; @@ -1195,13 +1196,13 @@ machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); /* We really don't care what LUID we give the user. */ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge, + if(cli_nt_login_network(&cli, nt_pipe_fnum, domain, user, smb_uid_low, (char *)local_challenge, ((smb_apasslen != 0) ? smb_apasswd : NULL), ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), &ctr, &info3) == False) { DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli); + cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); return False; @@ -1218,17 +1219,17 @@ machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); * send here. JRA. */ - if(cli_nt_logoff(&cli, &ctr) == False) { + if(cli_nt_logoff(&cli, nt_pipe_fnum, &ctr) == False) { DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ %s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli); + cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); return False; } #endif /* 0 */ - cli_nt_session_close(&cli); + cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); return True; -- cgit From e67a8d9d984dbdef307294358d7d9a7f4314ea09 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 14 Dec 1998 21:22:59 +0000 Subject: server_cryptkey() now calling cli_connectserverlist(). stupid microsoft idiotic *SMBSERVER connectionism added to cli_connect_serverlist(). also added check for protocol < LANMAN2. (This used to be commit c2bcb3a286f22ed4f0f55da2a3eb2bff17906fb1) --- source3/smbd/password.c | 78 +++---------------------------------------------- 1 file changed, 4 insertions(+), 74 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 726d93e404..7eed028a80 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -909,81 +909,11 @@ support for server level security ****************************************************************************/ struct cli_state *server_cryptkey(void) { - struct cli_state *cli; - fstring desthost; - struct in_addr dest_ip; - extern fstring local_machine; - char *p; - BOOL connected_ok = False; - struct nmb_name calling, called; - - cli = server_client(); - - if (!cli_initialise(cli)) - return NULL; - - p = lp_passwordserver(); - while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { - standard_sub_basic(desthost); - strupper(desthost); - - if(!resolve_name( desthost, &dest_ip, 0x20)) { - DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); - continue; - } - - if (cli_connect(cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",desthost)); - connected_ok = True; - break; - } - } - - if (!connected_ok) { - DEBUG(0,("password server not available\n")); - cli_shutdown(cli); - return NULL; - } - - make_nmb_name(&calling, local_machine, 0x0 , scope); - make_nmb_name(&called , desthost , 0x20, scope); - - if (!cli_session_request(cli, &calling, &called)) { - /* try with *SMBSERVER if the first name fails */ - cli_shutdown(cli); - make_nmb_name(&called , "*SMBSERVER", 0x20, scope); - if (!cli_initialise(cli) || - !cli_connect(cli, desthost, &dest_ip) || - !cli_session_request(cli, &calling, &called)) { - DEBUG(1,("%s rejected the session\n",desthost)); - cli_shutdown(cli); - return NULL; - } - } - - DEBUG(3,("got session\n")); - - if (!cli_negprot(cli)) { - DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(cli); - return NULL; - } - - if (cli->protocol < PROTOCOL_LANMAN2 || - !(cli->sec_mode & 1)) { - DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(cli); - return NULL; + if (cli_connect_serverlist(server_client(), lp_passwordserver())) + { + return server_client(); } - - DEBUG(3,("password server OK\n")); - - return cli; + return NULL; } /**************************************************************************** -- cgit From c4241b56628469227f84f9d0b7589d9bc07d7bd3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 12 Mar 1999 19:37:40 +0000 Subject: cli_setup_creds new arguments added. (This used to be commit 5fa3a3f710cfd3a51641d560a96bd08f92afca32) --- source3/smbd/password.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 7eed028a80..e1a4e66c40 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1114,7 +1114,9 @@ machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); return False; } - if(cli_nt_setup_creds(&cli, nt_pipe_fnum, trust_passwd) == False) { + if(cli_nt_setup_creds(&cli, nt_pipe_fnum, + cli.mach_acct, trust_passwd, SEC_CHAN_WKSTA) == False) + { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); cli_nt_session_close(&cli, nt_pipe_fnum); -- cgit From bd76e02ec43124e5666868e272b9b4bcfbccc99b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 19 Mar 1999 15:49:22 +0000 Subject: going to start adding inter-domain trust logons soon. (This used to be commit f9f594c03e220a0d902c5c3c5835948348b19fee) --- source3/smbd/password.c | 253 +++++++++++++++++++++++++----------------------- 1 file changed, 130 insertions(+), 123 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e1a4e66c40..68d75b933f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1018,151 +1018,158 @@ use this machine as the password server.\n")); /*********************************************************************** Do the same as security=server, but using NT Domain calls and a session - key from the machine password. + key from the workstation trust account password. ************************************************************************/ BOOL domain_client_validate( char *user, char *domain, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) { - uint16 nt_pipe_fnum; - unsigned char local_challenge[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_reponse[24]; - unsigned char trust_passwd[16]; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 info3; - struct cli_state cli; - uint32 smb_uid_low; - - /* - * Check that the requested domain is not our own machine name. - * If it is, we should never check the PDC here, we use our own local - * password file. - */ - - if(strequal( domain, global_myname)) { - DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); - return False; - } - - /* - * Next, check that the passwords given were encrypted. - */ - - if(((smb_apasslen != 24) && (smb_apasslen != 0)) || - ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) { - - /* - * Not encrypted - do so. - */ + uint16 nt_pipe_fnum; + unsigned char local_challenge[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_reponse[24]; + unsigned char trust_passwd[16]; + NET_ID_INFO_CTR ctr; + NET_USER_INFO_3 info3; + struct cli_state cli; + uint32 smb_uid_low; + + /* + * Check that the requested domain is not our own machine name. + * If it is, we should never check the PDC here, we use our own local + * password file. + */ + + if(strequal( domain, global_myname)) + { + DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); + return False; + } - DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); - generate_random_buffer( local_challenge, 8, False); - SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); - SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse); - smb_apasslen = 24; - smb_ntpasslen = 24; - smb_apasswd = (char *)local_lm_response; - smb_ntpasswd = (char *)local_nt_reponse; - } else { + /* + * Next, check that the passwords given were encrypted. + */ - /* - * Encrypted - get the challenge we sent for these - * responses. - */ + if(((smb_apasslen != 24) && (smb_apasslen != 0)) || + ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) + { + /* + * Not encrypted - do so. + */ + + DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); + generate_random_buffer( local_challenge, 8, False); + SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); + SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse); + smb_apasslen = 24; + smb_ntpasslen = 24; + smb_apasswd = (char *)local_lm_response; + smb_ntpasswd = (char *)local_nt_reponse; + } + else + { + /* + * Encrypted - get the challenge we sent for these + * responses. + */ - if (!last_challenge(local_challenge)) { - DEBUG(0,("domain_client_validate: no challenge done - password failed\n")); - return False; - } - } + if (!last_challenge(local_challenge)) + { + DEBUG(0,("domain_client_validate: no challenge done - password failed\n")); + return False; + } + } - /* - * Get the machine account password. - */ - if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) - { - return False; - } + /* + * Get the workstation trust account password. + */ + if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) + { + return False; + } - /* - * At this point, smb_apasswd points to the lanman response to - * the challenge in local_challenge, and smb_ntpasswd points to - * the NT response to the challenge in local_challenge. Ship - * these over the secure channel to a domain controller and - * see if they were valid. - */ + /* + * At this point, smb_apasswd points to the lanman response to + * the challenge in local_challenge, and smb_ntpasswd points to + * the NT response to the challenge in local_challenge. Ship + * these over the secure channel to a domain controller and + * see if they were valid. + */ if (!cli_connect_serverlist(&cli, lp_passwordserver())) { - DEBUG(0,("domain_client_validate: Domain password server not available.\n")); - return False; - } + DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + return False; + } - /* - * Ok - we have an anonymous connection to the IPC$ share. - * Now start the NT Domain stuff :-). - */ + /* + * Ok - we have an anonymous connection to the IPC$ share. + * Now start the NT Domain stuff :-). + */ + + if(cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum) == False) { + DEBUG(0,("domain_client_validate: unable to open the domain client session to \ + machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } - if(cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum) == False) { - DEBUG(0,("domain_client_validate: unable to open the domain client session to \ -machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } + if(cli_nt_setup_creds(&cli, nt_pipe_fnum, + cli.mach_acct, trust_passwd, SEC_CHAN_WKSTA) == False) + { + DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ + %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } - if(cli_nt_setup_creds(&cli, nt_pipe_fnum, - cli.mach_acct, trust_passwd, SEC_CHAN_WKSTA) == False) - { - DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ -%s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } + /* We really don't care what LUID we give the user. */ + generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - /* We really don't care what LUID we give the user. */ - generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - - if(cli_nt_login_network(&cli, nt_pipe_fnum, domain, user, smb_uid_low, (char *)local_challenge, - ((smb_apasslen != 0) ? smb_apasswd : NULL), - ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), - &ctr, &info3) == False) { - DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } + if (!cli_nt_login_network(&cli, nt_pipe_fnum, domain, user, smb_uid_low, (char *)local_challenge, + ((smb_apasslen != 0) ? smb_apasswd : NULL), + ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), + &ctr, &info3)) + { + DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ + %s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } - /* - * Here, if we really want it, we have lots of info about the user in info3. - */ + /* + * Here, if we really want it, we have lots of info about the user in info3. + * LKCLXXXX - really important to check things like "is this user acct + * locked out / disabled" etc!!!! + */ #if 0 - /* - * We don't actually need to do this - plus it fails currently with - * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to - * send here. JRA. - */ + /* + * We don't actually need to do this - plus it fails currently with + * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to + * send here. JRA. + */ - if(cli_nt_logoff(&cli, nt_pipe_fnum, &ctr) == False) { - DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } + if (!cli_nt_logoff(&cli, nt_pipe_fnum, &ctr)) + { + DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ + %s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } #endif /* 0 */ - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return True; + cli_nt_session_close(&cli, nt_pipe_fnum); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return True; } -- cgit From 43a460075a39148060d4193fcb9c62bfa4acc737 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 25 Mar 1999 13:54:31 +0000 Subject: SAM database "set user info". ---------------------------- - removed DOM_RID4 - removed SAMR_UNKNOWN_32 - added SAMR_SET_USERINFO (opcode 0x32) - added level 0x1 to SAMR_QUERY_DOM_INFO (needed for create user) - fixed pwdb_gethexpwd() it was failing on XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX - added mod_sam21pwd_entry() - preparing to call mod_sam21pwd_entry() - added "user session key" to user_struct.dc. this is md4(nt#) and is needed to decode user's clear-text passwords in SAMR_SET_USERINFO. - split code out in chgpasswd.c to decode 516 byte password buffers. (This used to be commit 2e58ed742435befe419aa366c4052019fede8c23) --- source3/smbd/password.c | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 68d75b933f..11fe69b103 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -156,7 +156,7 @@ register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest) +uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, uchar user_sess_key[16]) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -205,6 +205,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, vuser->guest = guest; fstrcpy(vuser->name,unix_name); fstrcpy(vuser->requested_name,requested_name); + memcpy(vuser->dc.user_sess_key, user_sess_key, sizeof(vuser->dc.user_sess_key)); vuser->n_sids = 0; vuser->sids = NULL; @@ -412,7 +413,7 @@ return True if the password is correct, False otherwise BOOL pass_check_smb(char *user, char *domain, uchar *chal, uchar *lm_pwd, uchar *nt_pwd, - struct passwd *pwd) + struct passwd *pwd, uchar user_sess_key[16]) { struct passwd *pass; struct smb_passwd *smb_pass; @@ -467,6 +468,14 @@ BOOL pass_check_smb(char *user, char *domain, if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd)) { + if (user_sess_key != NULL) + { + mdfour(user_sess_key, smb_pass->smb_nt_passwd, 16); +#ifdef DEBUG_PASSWORD + DEBUG(100,("user session key: ")); + dump_data(100, user_sess_key, 16); +#endif + } return(True); } @@ -479,7 +488,8 @@ check if a username/password pair is OK either via the system password database or the encrypted SMB password database return True if the password is correct, False otherwise ****************************************************************************/ -BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) +BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, + uchar user_sess_key[16]) { if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { @@ -493,7 +503,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) } return pass_check_smb(user, global_myworkgroup, - challenge, (uchar *)password, (uchar *)password, pwd); + challenge, (uchar *)password, (uchar *)password, pwd, user_sess_key); } return pass_check(user, password, pwlen, pwd, @@ -536,7 +546,8 @@ BOOL user_ok(char *user,int snum) /**************************************************************************** validate a group username entry. Return the username or NULL ****************************************************************************/ -static char *validate_group(char *group,char *password,int pwlen,int snum) +static char *validate_group(char *group,char *password,int pwlen,int snum, + uchar user_sess_key[16]) { #if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT) { @@ -545,7 +556,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && - password_ok(user,password,pwlen,NULL)) { + password_ok(user,password,pwlen,NULL, user_sess_key)) { endnetgrent(); return(user); } @@ -567,7 +578,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) static fstring name; fstrcpy(name,*member); if (user_ok(name,snum) && - password_ok(name,password,pwlen,NULL)) + password_ok(name,password,pwlen,NULL, user_sess_key)) return(&name[0]); member++; } @@ -580,7 +591,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (pwd = getpwent ()) { if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) { /* This Entry have PASSWORD and same GID then check pwd */ - if (password_ok(NULL, password, pwlen, pwd)) { + if (password_ok(NULL, password, pwlen, pwd, user_sess_key)) { fstrcpy(tm, pwd->pw_name); endpwent (); return tm; @@ -633,14 +644,14 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL); + ok = password_ok(user,password, pwlen, NULL, vuser->dc.user_sess_key); if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); } /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->name,snum) && - password_ok(vuser->name, password, pwlen, NULL)) { + password_ok(vuser->name, password, pwlen, NULL, vuser->dc.user_sess_key)) { fstrcpy(user, vuser->name); vuser->guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); @@ -664,7 +675,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstrcpy(user2,auser); if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen, NULL)) { + if (password_ok(user2,password, pwlen, NULL, vuser->dc.user_sess_key)) { ok = True; fstrcpy(user,user2); DEBUG(3,("ACCEPTED: session list username and given password ok\n")); @@ -703,7 +714,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, { if (*auser == '@') { - auser = validate_group(auser+1,password,pwlen,snum); + auser = validate_group(auser+1,password,pwlen,snum, vuser->dc.user_sess_key); if (auser) { ok = True; @@ -716,7 +727,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstring user2; fstrcpy(user2,auser); if (user_ok(user2,snum) && - password_ok(user2,password,pwlen,NULL)) + password_ok(user2,password,pwlen,NULL, vuser->dc.user_sess_key)) { ok = True; fstrcpy(user,user2); -- cgit From 150645f955d1f15b0ea43069020070424f774521 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 6 May 1999 18:05:45 +0000 Subject: Jani Jaakkola's "getpwuid() / getpwnam()" hash-cache-hack (This used to be commit 899fc053c50448db65092d9f25fea99433cfb29f) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 11fe69b103..daead8bb82 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -224,7 +224,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->real_name, "\0"); if (lp_unix_realname()) { - if ((pwfile=getpwnam(vuser->name))!= NULL) + if ((pwfile=hashed_getpwnam(vuser->name))!= NULL) { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); fstrcpy(vuser->real_name, pwfile->pw_gecos); -- cgit From 731c7f2ecfe17651506ba05b88358360e4654a37 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 13 Jun 1999 04:14:24 +0000 Subject: Moved code that changes the pw_passwd entry (i.e shadow password and weird unixware stuff) into _Get_Pwnam() to fix a memory allocation bug. Note that the Get_Pwnam() function now returns a const struct passwd * as a hint to other developers not to change entries in the struct passwd. (This used to be commit 36d7cb4ccc42268e8e6a7b783c945d1853624958) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index daead8bb82..c05b82ef15 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -415,7 +415,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd, uchar user_sess_key[16]) { - struct passwd *pass; + const struct passwd *pass; struct smb_passwd *smb_pass; if (!lm_pwd || !nt_pwd) @@ -877,7 +877,7 @@ BOOL check_hosts_equiv(char *user) { char *fname = NULL; pstring rhostsfile; - struct passwd *pass = Get_Pwnam(user,True); + const struct passwd *pass = Get_Pwnam(user,True); if (!pass) return(False); -- cgit From 73891ca8e4f6cca6aa8bb0ae043f660a64baa056 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 29 Jun 1999 18:47:06 +0000 Subject: improving authentication code (tidyup). (This used to be commit ab1a6aa42db5217f025941fb5107436556bc23b7) --- source3/smbd/password.c | 147 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 102 insertions(+), 45 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c05b82ef15..14a63c6ef4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -292,51 +292,78 @@ static BOOL update_smbpassword_file(char *user, char *password) /**************************************************************************** core of smb password checking routine. ****************************************************************************/ -BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8) +static BOOL smb_pwd_check_ntlmv1(char *password, unsigned char *part_passwd, + unsigned char *c8) { /* Finish the encryption of part_passwd. */ - unsigned char p21[21]; unsigned char p24[24]; if (part_passwd == NULL) DEBUG(10,("No password set - allowing access\n")); /* No password set - always true ! */ if (part_passwd == NULL) - return 1; + return True; - memset(p21,'\0',21); - memcpy(p21,part_passwd,16); - E_P24(p21, c8, p24); + SMBOWFencrypt(part_passwd, c8, p24); #if DEBUG_PASSWORD - { - int i; - DEBUG(100,("Part password (P16) was |")); - for(i = 0; i < 16; i++) - DEBUG(100,("%X ", (unsigned char)part_passwd[i])); - DEBUG(100,("|\n")); - DEBUG(100,("Password from client was |")); - for(i = 0; i < 24; i++) - DEBUG(100,("%X ", (unsigned char)password[i])); - DEBUG(100,("|\n")); - DEBUG(100,("Given challenge was |")); - for(i = 0; i < 8; i++) - DEBUG(100,("%X ", (unsigned char)c8[i])); - DEBUG(100,("|\n")); - DEBUG(100,("Value from encryption was |")); - for(i = 0; i < 24; i++) - DEBUG(100,("%X ", (unsigned char)p24[i])); - DEBUG(100,("|\n")); - } + DEBUG(100,("Part password (P16) was |")); + dump_data(100, part_passwd, 16); + DEBUG(100,("Password from client was |")); + dump_data(100, password, 24); + DEBUG(100,("Given challenge was |")); + dump_data(100, c8, 8); + DEBUG(100,("Value from encryption was |")); + dump_data(100, p24, 24); #endif return (memcmp(p24, password, 24) == 0); } +/**************************************************************************** +core of smb password checking routine. +****************************************************************************/ +static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len, + unsigned char *part_passwd, + unsigned char const *c8, + const char *user, const char *domain) +{ + /* Finish the encryption of part_passwd. */ + unsigned char kr[16]; + + if (part_passwd == NULL) + { + DEBUG(10,("No password set - allowing access\n")); + } + /* No password set - always true ! */ + if (part_passwd == NULL) + { + return True; + } + + ntv2_owf_gen(part_passwd, user, domain, kr); + SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, kr); + +#if DEBUG_PASSWORD + DEBUG(100,("Part password (P16) was |")); + dump_data(100, part_passwd, 16); + DEBUG(100,("Password from client was |")); + dump_data(100, password, pwd_len); + DEBUG(100,("Given challenge was |")); + dump_data(100, c8, 8); + DEBUG(100,("Value from encryption was |")); + dump_data(100, kr, 16); +#endif + + return (memcmp(kr, password, 16) == 0); +} + /**************************************************************************** Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], - uchar lm_pass[24], uchar nt_pass[24]) + const char *user, const char *domain, + uchar *lm_pass, size_t lm_pwd_len, + uchar *nt_pass, size_t nt_pwd_len) { uchar challenge[8]; @@ -345,7 +372,8 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], DEBUG(4,("Checking SMB password for user %s\n", smb_pass->unix_name)); - if(smb_pass->acct_ctrl & ACB_DISABLED) { + if (smb_pass->acct_ctrl & ACB_DISABLED) + { DEBUG(3,("account for user %s was disabled.\n", smb_pass->unix_name)); return(False); @@ -366,35 +394,59 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], memcpy(challenge, chal, 8); } - if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) { + if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) + { /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). */ - DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check((char *)nt_pass, + if (lp_server_ntlmv2()) + { + DEBUG(4,("smb_password_ok: Check NTLMv2 password\n")); + if (smb_pwd_check_ntlmv2(nt_pass, nt_pwd_len, + (uchar *)smb_pass->smb_nt_passwd, + challenge, user, domain)) + { + return True; + } + } + if (lp_server_ntlmv2() != True && nt_pwd_len == 24) + { + DEBUG(4,("smb_password_ok: Check NT MD4 password\n")); + if (smb_pwd_check_ntlmv1((char *)nt_pass, (uchar *)smb_pass->smb_nt_passwd, - challenge)) { - DEBUG(4,("NT MD4 password check succeeded\n")); - return(True); + challenge)) + { + DEBUG(4,("NT MD4 password check succeeded\n")); + return True; + } } DEBUG(4,("NT MD4 password check failed\n")); } + if (lp_server_ntlmv2() == False) + { + DEBUG(4,("Not checking LM MD4 password\n")); + return False; + } + /* Try against the lanman password. smb_pass->smb_passwd == NULL means no password, allow access. */ DEBUG(4,("Checking LM MD4 password\n")); - if((smb_pass->smb_passwd == NULL) && - (smb_pass->acct_ctrl & ACB_PWNOTREQ)) { + if ((smb_pass->smb_passwd == NULL) && + (smb_pass->acct_ctrl & ACB_PWNOTREQ)) + { DEBUG(4,("no password required for user %s\n", smb_pass->unix_name)); return True; } - if((smb_pass->smb_passwd != NULL) && - smb_password_check((char *)lm_pass, - (uchar *)smb_pass->smb_passwd, challenge)) { + if ((smb_pass->smb_passwd != NULL) && + smb_pwd_check_ntlmv1((char *)lm_pass, + (uchar *)smb_pass->smb_passwd, + challenge)) + { DEBUG(4,("LM MD4 password check succeeded\n")); return(True); } @@ -411,8 +463,9 @@ SMB hash return True if the password is correct, False otherwise ****************************************************************************/ -BOOL pass_check_smb(char *user, char *domain, - uchar *chal, uchar *lm_pwd, uchar *nt_pwd, +BOOL pass_check_smb(char *user, char *domain, uchar *chal, + uchar *lm_pwd, size_t lm_pwd_len, + uchar *nt_pwd, size_t nt_pwd_len, struct passwd *pwd, uchar user_sess_key[16]) { const struct passwd *pass; @@ -466,7 +519,9 @@ BOOL pass_check_smb(char *user, char *domain, return(True); } - if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd)) + if (smb_password_ok(smb_pass, chal, user, domain, + lm_pwd, lm_pwd_len, + nt_pwd, nt_pwd_len)) { if (user_sess_key != NULL) { @@ -479,7 +534,7 @@ BOOL pass_check_smb(char *user, char *domain, return(True); } - DEBUG(3,("Error smb_password_check failed\n")); + DEBUG(3,("Error pass_check_smb failed\n")); return False; } @@ -491,9 +546,9 @@ return True if the password is correct, False otherwise BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, uchar user_sess_key[16]) { - if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) + if (pwlen >= 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { - /* if 24 bytes long assume it is an encrypted password */ + /* if 24 bytes or longer assume it is an encrypted password */ uchar challenge[8]; if (!last_challenge(challenge)) @@ -503,7 +558,9 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, } return pass_check_smb(user, global_myworkgroup, - challenge, (uchar *)password, (uchar *)password, pwd, user_sess_key); + challenge, (uchar *)password, + pwlen, (uchar *)password, pwlen, + pwd, user_sess_key); } return pass_check(user, password, pwlen, pwd, -- cgit From ec711742c0b656e8c660f1d990e16b64addbf119 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Tue, 6 Jul 1999 21:25:42 +0000 Subject: smb_password_ok() checking incorrectly whether lm password exists. when lmcompatibilitylevel=0x2 on nt sp4+ clients, lm# is not sent. (This used to be commit e655e68474dd0234b49c23a07d9cb8bdd8f6016a) --- source3/smbd/password.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 14a63c6ef4..026fd5c10c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -85,7 +85,7 @@ get the last challenge sent ********************************************************************/ static BOOL last_challenge(unsigned char *challenge) { - if (!challenge_sent) return(False); + if (!challenge_sent) return False; memcpy(challenge,saved_challenge,8); return(True); } @@ -367,7 +367,10 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], { uchar challenge[8]; - if (!lm_pass || !smb_pass) return(False); + if (smb_pass == NULL) + { + return False; + } DEBUG(4,("Checking SMB password for user %s\n", smb_pass->unix_name)); @@ -376,7 +379,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], { DEBUG(3,("account for user %s was disabled.\n", smb_pass->unix_name)); - return(False); + return False; } if (chal == NULL) @@ -473,7 +476,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (!lm_pwd || !nt_pwd) { - return(False); + return False; } if (pwd != NULL && user == NULL) @@ -489,7 +492,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (pass == NULL) { DEBUG(3,("Couldn't find user %s\n",user)); - return(False); + return False; } smb_pass = getsmbpwnam(user); @@ -497,20 +500,20 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (smb_pass == NULL) { DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); - return(False); + return False; } /* Quit if the account was disabled. */ if(smb_pass->acct_ctrl & ACB_DISABLED) { DEBUG(3,("account for user %s was disabled.\n", user)); - return(False); + return False; } /* Ensure the uid's match */ if (smb_pass->unix_uid != pass->pw_uid) { DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); - return(False); + return False; } if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords()) @@ -722,7 +725,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, { char *auser; char *user_list = strdup(session_users); - if (!user_list) return(False); + if (!user_list) return False; for (auser=strtok(user_list,LIST_SEP); !ok && auser; @@ -937,7 +940,7 @@ BOOL check_hosts_equiv(char *user) const struct passwd *pass = Get_Pwnam(user,True); if (!pass) - return(False); + return False; fname = lp_hosts_equiv(); @@ -959,7 +962,7 @@ BOOL check_hosts_equiv(char *user) } } - return(False); + return False; } @@ -1000,7 +1003,7 @@ BOOL server_validate(char *user, char *domain, if (!cli->initialised) { DEBUG(1,("password server %s is not connected\n", cli->desthost)); - return(False); + return False; } if(badpass[0] == 0) @@ -1075,7 +1078,7 @@ use this machine as the password server.\n")); if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); cli_ulogoff(cli); - return(False); + return False; } -- cgit From 527820d30646f3954155a509752e2b08c96b1448 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 7 Jul 1999 16:44:38 +0000 Subject: oops, refused lm when ntlmv2 was true not false/auto. oops! (This used to be commit 6b4b24d2208b1b076dfc2f7202917ca0acaeb398) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 026fd5c10c..b10bc33a3a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -426,7 +426,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], DEBUG(4,("NT MD4 password check failed\n")); } - if (lp_server_ntlmv2() == False) + if (lp_server_ntlmv2() == True) { DEBUG(4,("Not checking LM MD4 password\n")); return False; -- cgit From 92b8937bae9139e3f7464b8cba445e929c802381 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 15 Jul 1999 17:50:27 +0000 Subject: added %d %d to error message, try to track down the uid / smb_uid mismatch (This used to be commit ec918ba144e7c1bd1689007143ca2b8bee604768) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b10bc33a3a..1f1ca12713 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -504,7 +504,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, } /* Quit if the account was disabled. */ - if(smb_pass->acct_ctrl & ACB_DISABLED) { + if (smb_pass->acct_ctrl & ACB_DISABLED) { DEBUG(3,("account for user %s was disabled.\n", user)); return False; } @@ -512,7 +512,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, /* Ensure the uid's match */ if (smb_pass->unix_uid != pass->pw_uid) { - DEBUG(3,("Error : UNIX and SMB uids in password files do not match !\n")); + DEBUG(3,("Error : UNIX (%d) and SMB (%d) uids in password files do not match !\n", pass->pw_uid, smb_pass->unix_uid)); return False; } -- cgit From 0262b2a6b49d3a2418e3f335f06cbb227382bc86 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Jul 1999 22:03:15 +0000 Subject: copy of password struct needed to be made prior to calling copy_passwd_struct found by Bertl . (This used to be commit 93298bca1c573532c5250c84bac39cf9214ba3b5) --- source3/smbd/password.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1f1ca12713..022d432787 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -472,6 +472,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, struct passwd *pwd, uchar user_sess_key[16]) { const struct passwd *pass; + struct passwd pw; struct smb_passwd *smb_pass; if (!lm_pwd || !nt_pwd) @@ -487,12 +488,13 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, else { pass = Get_Pwnam(user,True); - } - - if (pass == NULL) - { - DEBUG(3,("Couldn't find user %s\n",user)); - return False; + if (pass == NULL) + { + DEBUG(3,("Couldn't find user %s\n",user)); + return False; + } + memcpy(&pw, pass, sizeof(struct passwd)); + pass = &pw; } smb_pass = getsmbpwnam(user); -- cgit From 33ed8059a2bbf8e8a43aee9ca9d6da736e84d686 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 16 Jul 1999 22:23:45 +0000 Subject: NTLMv2 check being actioned when NT password response was only 24 chars. added check to ensure response is more than 24 chars before bothering to do an NTLMv2 check. (This used to be commit 7a58895ff26fcad09ee45de99086739bf5761fd9) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 022d432787..6ec290ca25 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -402,7 +402,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). */ - if (lp_server_ntlmv2()) + if (lp_server_ntlmv2() != False && nt_pwd_len > 24) { DEBUG(4,("smb_password_ok: Check NTLMv2 password\n")); if (smb_pwd_check_ntlmv2(nt_pass, nt_pwd_len, -- cgit From 6f9105c853020fde1691a28cd707d6d3f6561b4d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 21 Oct 1999 16:53:50 +0000 Subject: various. debug levels changed. nmbd doesn't need libsmb/clienttrust.c. samr_lookup_rids() moved to a dynamic memory structure not a static one limited to 32 RIDs. cli_pipe.c reading wasn't checking ERRmoredata when DOS error codes negotiated (this terminates MSRPC code with prejudice). (This used to be commit 8976eca2db43576c32069dcda017e8777048e007) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6ec290ca25..a98c6289b8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1191,7 +1191,7 @@ BOOL domain_client_validate( char *user, char *domain, } if(cli_nt_setup_creds(&cli, nt_pipe_fnum, - cli.mach_acct, trust_passwd, SEC_CHAN_WKSTA) == False) + cli.mach_acct, global_myname, trust_passwd, SEC_CHAN_WKSTA) == False) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); -- cgit From 902b53dcc0933045980ed5d7df4959eee6f016d3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 29 Oct 1999 15:53:18 +0000 Subject: cli_nt_setup_creds() returns uint32 NT status code not a BOOL. removed all comparisons to if (fn() == False), replaced with if (!fn()). (This used to be commit fdef97eb7c20a33b26104661cd010baebcb4bdcd) --- source3/smbd/password.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a98c6289b8..1612b8264f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -278,7 +278,8 @@ static BOOL update_smbpassword_file(char *user, char *password) /* Here, the flag is one, because we want to ignore the XXXXXXX'd out password */ ret = change_oem_password( smbpw, password, True); - if (ret == False) { + if (!ret) + { DEBUG(3,("change_oem_password returned False\n")); } @@ -1181,7 +1182,7 @@ BOOL domain_client_validate( char *user, char *domain, * Now start the NT Domain stuff :-). */ - if(cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum) == False) { + if (!cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum)) { DEBUG(0,("domain_client_validate: unable to open the domain client session to \ machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); cli_nt_session_close(&cli, nt_pipe_fnum); @@ -1191,7 +1192,7 @@ BOOL domain_client_validate( char *user, char *domain, } if(cli_nt_setup_creds(&cli, nt_pipe_fnum, - cli.mach_acct, global_myname, trust_passwd, SEC_CHAN_WKSTA) == False) + cli.mach_acct, global_myname, trust_passwd, SEC_CHAN_WKSTA) != 0x0) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); -- cgit From 24a069eac302069559c6347b24276e7f1a04cc91 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 20 Nov 1999 20:54:29 +0000 Subject: modified domain_client_validate to take trust account name / type. this is to pass DOMAIN_NAME$ and SEC_CHAN_DOMAIN instead of WKSTA_NAME$ and SEC_CHAN_WKSTA. modified check_domain_security to determine if domain name is own domain, and to use wksta trust account if so, otherwise check "trusting domains" parameter and use inter-domain trust account if so, otherwise return False. (This used to be commit 97ec74e1fa99d773812d2df402251fafb76b181c) --- source3/smbd/password.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1612b8264f..f74cc49eca 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1095,7 +1095,8 @@ use this machine as the password server.\n")); key from the workstation trust account password. ************************************************************************/ -BOOL domain_client_validate( char *user, char *domain, +BOOL domain_client_validate( char *user, char *domain, char *server_list, + char *acct_name, uint16 acct_type, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen) { @@ -1108,6 +1109,10 @@ BOOL domain_client_validate( char *user, char *domain, NET_USER_INFO_3 info3; struct cli_state cli; uint32 smb_uid_low; + fstring trust_acct; + + fstrcpy(trust_acct, acct_name); + fstrcat(trust_acct, "$"); /* * Check that the requested domain is not our own machine name. @@ -1126,7 +1131,7 @@ BOOL domain_client_validate( char *user, char *domain, */ if(((smb_apasslen != 24) && (smb_apasslen != 0)) || - ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) + ((smb_ntpasslen <= 24) && (smb_ntpasslen != 0))) { /* * Not encrypted - do so. @@ -1158,7 +1163,7 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the workstation trust account password. */ - if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) + if (!trust_get_passwd( trust_passwd, domain, acct_name)) { return False; } @@ -1171,7 +1176,7 @@ BOOL domain_client_validate( char *user, char *domain, * see if they were valid. */ - if (!cli_connect_serverlist(&cli, lp_passwordserver())) + if (!cli_connect_serverlist(&cli, server_list)) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); return False; @@ -1192,7 +1197,7 @@ BOOL domain_client_validate( char *user, char *domain, } if(cli_nt_setup_creds(&cli, nt_pipe_fnum, - cli.mach_acct, global_myname, trust_passwd, SEC_CHAN_WKSTA) != 0x0) + trust_acct, global_myname, trust_passwd, acct_type) != 0x0) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); -- cgit From 27b8df4d9bc31fc73f7db6ceed24a6fca1271d3f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 20 Nov 1999 21:59:16 +0000 Subject: attempting to establish inter-domain trust relationships. modified smbpasswd so it can be used to set up inter-domain trust account. (This used to be commit 99ec0620c3bf4af96440c684f880d414659de2e9) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f74cc49eca..b279e76f41 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1247,8 +1247,10 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, } #endif /* 0 */ +#if 0 cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); +#endif return True; } -- cgit From 387cc182e6a8a500fe4e0115b33230c6acca8084 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sat, 20 Nov 1999 22:05:31 +0000 Subject: oops, #ifdef'd cli_shutdown out, as the fun has _already_ started: NT refuses to play nice, and establish a trust relationship. (This used to be commit 98c42764fba365d612a8ae4b3172b03367066112) --- source3/smbd/password.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b279e76f41..2f0ab6e137 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1247,10 +1247,9 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, } #endif /* 0 */ -#if 0 cli_nt_session_close(&cli, nt_pipe_fnum); cli_ulogoff(&cli); cli_shutdown(&cli); -#endif + return True; } -- cgit From 4081147c31919a973ce1859394d0f5a49a0c2f39 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 17:11:00 +0000 Subject: adding user session key into network netlogon response. (This used to be commit c73f6b0d02fa7700319ba696f54296006167e5d1) --- source3/smbd/password.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2f0ab6e137..690e2e5f5c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -467,16 +467,24 @@ SMB hash return True if the password is correct, False otherwise ****************************************************************************/ -BOOL pass_check_smb(char *user, char *domain, uchar *chal, +BOOL pass_check_smb(struct smb_passwd *smb_pass, char *domain, uchar *chal, uchar *lm_pwd, size_t lm_pwd_len, uchar *nt_pwd, size_t nt_pwd_len, struct passwd *pwd, uchar user_sess_key[16]) { const struct passwd *pass; struct passwd pw; - struct smb_passwd *smb_pass; + char *user = NULL; - if (!lm_pwd || !nt_pwd) + if (smb_pass == NULL) + { + DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); + return False; + } + + user = smb_pass->unix_name; + + if (lm_pwd == NULL || nt_pwd == NULL) { return False; } @@ -498,14 +506,6 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, pass = &pw; } - smb_pass = getsmbpwnam(user); - - if (smb_pass == NULL) - { - DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); - return False; - } - /* Quit if the account was disabled. */ if (smb_pass->acct_ctrl & ACB_DISABLED) { DEBUG(3,("account for user %s was disabled.\n", user)); @@ -563,7 +563,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, return False; } - return pass_check_smb(user, global_myworkgroup, + return pass_check_smb(getsmbpwnam(user), global_myworkgroup, challenge, (uchar *)password, pwlen, (uchar *)password, pwlen, pwd, user_sess_key); -- cgit From 680dcc934182544aa49a4a426f2263c1aaedd4aa Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 17:27:20 +0000 Subject: hmmm... have to add client-side support in domain_client_validate() to _use_ user session key. (This used to be commit be6a6b13939798a9c7242b38864f0ce842391a74) --- source3/smbd/password.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 690e2e5f5c..3d7a35fac8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1097,8 +1097,9 @@ use this machine as the password server.\n")); BOOL domain_client_validate( char *user, char *domain, char *server_list, char *acct_name, uint16 acct_type, - char *smb_apasswd, int smb_apasslen, - char *smb_ntpasswd, int smb_ntpasslen) + char *smb_apasswd, int smb_apasslen, + char *smb_ntpasswd, int smb_ntpasslen, + uchar user_sess_key[16]) { uint16 nt_pipe_fnum; unsigned char local_challenge[8]; -- cgit From 32b9508d066f002e778873edc19266a6d897f922 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 21 Nov 1999 19:59:56 +0000 Subject: implement server-side generation of NTLMv2 session key. YESSS :-) (This used to be commit 1092b4f6fbdf3770c0dab756b982a562def1738e) --- source3/smbd/password.c | 37 ++++++++++++++++++++++++++----------- 1 file changed, 26 insertions(+), 11 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3d7a35fac8..010272b807 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -294,7 +294,8 @@ static BOOL update_smbpassword_file(char *user, char *password) core of smb password checking routine. ****************************************************************************/ static BOOL smb_pwd_check_ntlmv1(char *password, unsigned char *part_passwd, - unsigned char *c8) + unsigned char *c8, + uchar sess_key[16]) { /* Finish the encryption of part_passwd. */ unsigned char p24[24]; @@ -306,6 +307,11 @@ static BOOL smb_pwd_check_ntlmv1(char *password, unsigned char *part_passwd, return True; SMBOWFencrypt(part_passwd, c8, p24); + if (sess_key != NULL) + { + SMBsesskeygen_ntv1(part_passwd, NULL, sess_key); + } + #if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |")); dump_data(100, part_passwd, 16); @@ -325,10 +331,12 @@ core of smb password checking routine. static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len, unsigned char *part_passwd, unsigned char const *c8, - const char *user, const char *domain) + const char *user, const char *domain, + char *sess_key) { /* Finish the encryption of part_passwd. */ unsigned char kr[16]; + unsigned char resp[16]; if (part_passwd == NULL) { @@ -341,7 +349,11 @@ static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len, } ntv2_owf_gen(part_passwd, user, domain, kr); - SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, kr); + SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, resp); + if (sess_key != NULL) + { + SMBsesskeygen_ntv2(kr, resp, sess_key); + } #if DEBUG_PASSWORD DEBUG(100,("Part password (P16) was |")); @@ -351,10 +363,10 @@ static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len, DEBUG(100,("Given challenge was |")); dump_data(100, c8, 8); DEBUG(100,("Value from encryption was |")); - dump_data(100, kr, 16); + dump_data(100, resp, 16); #endif - return (memcmp(kr, password, 16) == 0); + return (memcmp(resp, password, 16) == 0); } /**************************************************************************** @@ -364,7 +376,8 @@ static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len, BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], const char *user, const char *domain, uchar *lm_pass, size_t lm_pwd_len, - uchar *nt_pass, size_t nt_pwd_len) + uchar *nt_pass, size_t nt_pwd_len, + uchar sess_key[16]) { uchar challenge[8]; @@ -408,7 +421,8 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], DEBUG(4,("smb_password_ok: Check NTLMv2 password\n")); if (smb_pwd_check_ntlmv2(nt_pass, nt_pwd_len, (uchar *)smb_pass->smb_nt_passwd, - challenge, user, domain)) + challenge, user, domain, + sess_key)) { return True; } @@ -418,7 +432,8 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], DEBUG(4,("smb_password_ok: Check NT MD4 password\n")); if (smb_pwd_check_ntlmv1((char *)nt_pass, (uchar *)smb_pass->smb_nt_passwd, - challenge)) + challenge, + sess_key)) { DEBUG(4,("NT MD4 password check succeeded\n")); return True; @@ -449,7 +464,7 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], if ((smb_pass->smb_passwd != NULL) && smb_pwd_check_ntlmv1((char *)lm_pass, (uchar *)smb_pass->smb_passwd, - challenge)) + challenge, NULL)) { DEBUG(4,("LM MD4 password check succeeded\n")); return(True); @@ -527,11 +542,11 @@ BOOL pass_check_smb(struct smb_passwd *smb_pass, char *domain, uchar *chal, if (smb_password_ok(smb_pass, chal, user, domain, lm_pwd, lm_pwd_len, - nt_pwd, nt_pwd_len)) + nt_pwd, nt_pwd_len, + user_sess_key)) { if (user_sess_key != NULL) { - mdfour(user_sess_key, smb_pass->smb_nt_passwd, 16); #ifdef DEBUG_PASSWORD DEBUG(100,("user session key: ")); dump_data(100, user_sess_key, 16); -- cgit From 0d44ff9a765f2e89be8b0ee99ec7c907e7c225c3 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 29 Nov 1999 21:47:14 +0000 Subject: attempting to resolve the issue that multiple servers often specified in parameters to connect to \PIPE\NETLOGON. (This used to be commit d1986ade30bdcac1f49707221a3e5a5ae597ce62) --- source3/smbd/password.c | 64 +++++++++---------------------------------------- 1 file changed, 11 insertions(+), 53 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 010272b807..fa6f2b06e3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1116,16 +1116,15 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, char *smb_ntpasswd, int smb_ntpasslen, uchar user_sess_key[16]) { - uint16 nt_pipe_fnum; unsigned char local_challenge[8]; unsigned char local_lm_response[24]; unsigned char local_nt_reponse[24]; unsigned char trust_passwd[16]; NET_ID_INFO_CTR ctr; NET_USER_INFO_3 info3; - struct cli_state cli; uint32 smb_uid_low; fstring trust_acct; + fstring srv_name; fstrcpy(trust_acct, acct_name); fstrcat(trust_acct, "$"); @@ -1192,50 +1191,31 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, * see if they were valid. */ - if (!cli_connect_serverlist(&cli, server_list)) - { - DEBUG(0,("domain_client_validate: Domain password server not available.\n")); - return False; - } - /* * Ok - we have an anonymous connection to the IPC$ share. * Now start the NT Domain stuff :-). */ - if (!cli_nt_session_open(&cli, PIPE_NETLOGON, &nt_pipe_fnum)) { - DEBUG(0,("domain_client_validate: unable to open the domain client session to \ - machine %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } - - if(cli_nt_setup_creds(&cli, nt_pipe_fnum, - trust_acct, global_myname, trust_passwd, acct_type) != 0x0) + if(cli_nt_setup_creds(server_list, global_myname, trust_acct, + trust_passwd, acct_type, srv_name) != 0x0) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ - %s. Error was : %s.\n", cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); + %s.\n", srv_name)); return False; } /* We really don't care what LUID we give the user. */ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - if (!cli_nt_login_network(&cli, nt_pipe_fnum, domain, user, smb_uid_low, (char *)local_challenge, - ((smb_apasslen != 0) ? smb_apasswd : NULL), - ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), - &ctr, &info3)) + if (!cli_nt_login_network(srv_name, global_myname, + domain, user, + smb_uid_low, (char *)local_challenge, + ((smb_apasslen != 0) ? smb_apasswd : NULL), + ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), + &ctr, &info3)) { DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ - %s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); + %s to Domain controller %s.\n", user, domain, srv_name)); return False; } @@ -1245,27 +1225,5 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, * locked out / disabled" etc!!!! */ -#if 0 - /* - * We don't actually need to do this - plus it fails currently with - * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to - * send here. JRA. - */ - - if (!cli_nt_logoff(&cli, nt_pipe_fnum, &ctr)) - { - DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ - %s to Domain controller %s. Error was %s.\n", user, domain, cli.desthost, cli_errstr(&cli))); - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } -#endif /* 0 */ - - cli_nt_session_close(&cli, nt_pipe_fnum); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return True; } -- cgit From c15b95cd1ede75b38d3a2c5192f2d1fd2a310c9a Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Wed, 1 Dec 1999 21:47:30 +0000 Subject: cli_session_setup() now takes an extra argument (host name). hey, what the heck is a cli_session_setup() call doing in here??? this should use cli_establish_connection()server! (This used to be commit fa054c96c62ed0f0a0c6649a7ad7a143fe09694b) --- source3/smbd/password.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fa6f2b06e3..3e4a856bfb 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1042,7 +1042,8 @@ BOOL server_validate(char *user, char *domain, */ if(!tested_password_server) { - if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), + if (cli_session_setup(cli, global_myname, + user, (char *)badpass, sizeof(badpass), (char *)badpass, sizeof(badpass), domain)) { /* @@ -1087,7 +1088,8 @@ use this machine as the password server.\n")); * not guest enabled, we can try with the real password. */ - if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + if (!cli_session_setup(cli, global_myname, + user, pass, passlen, ntpass, ntpasslen, domain)) { DEBUG(1,("password server %s rejected the password\n", cli->desthost)); return False; } -- cgit From b96e4e4f7d80bf783aeea1592fbca58769a58e1d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 2 Dec 1999 19:07:13 +0000 Subject: domain_client_validate() no longer takes serverlist, it calls get_any_dc_name(). (This used to be commit e21367c0ebdc5e202cdc39d50950bff089bf67f8) --- source3/smbd/password.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3e4a856bfb..c14b50d3a6 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1112,7 +1112,7 @@ use this machine as the password server.\n")); key from the workstation trust account password. ************************************************************************/ -BOOL domain_client_validate( char *user, char *domain, char *server_list, +BOOL domain_client_validate( char *user, char *domain, char *acct_name, uint16 acct_type, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen, @@ -1143,6 +1143,13 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, return False; } + if (!get_any_dc_name(domain, srv_name)) + { + DEBUG(3,("domain_client_validate: could not find domain %s\n", + domain)); + return False; + } + /* * Next, check that the passwords given were encrypted. */ @@ -1198,8 +1205,8 @@ BOOL domain_client_validate( char *user, char *domain, char *server_list, * Now start the NT Domain stuff :-). */ - if(cli_nt_setup_creds(server_list, global_myname, trust_acct, - trust_passwd, acct_type, srv_name) != 0x0) + if(cli_nt_setup_creds(srv_name, global_myname, trust_acct, + trust_passwd, acct_type) != 0x0) { DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ %s.\n", srv_name)); -- cgit From a0ba234cf9b40adf6b5390e4e67730163a42883f Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Mon, 6 Dec 1999 00:44:32 +0000 Subject: the first independent msrpc daemon - lsarpcd. one horrible cut / paste job from smbd, plus a code split of shared components between the two. the job is not _yet_ complete, as i need to be able to do a become_user() call for security reasons. i picked lsarpcd first because you don't _need_ security on it (microsoft botched so badly on this one, it's not real. at least they fixed this in nt5 with restrictanonymous=0x2). fixing this involves sending the current smb and unix credentials down the unix pipe so that the daemon it eventually goes to can pick them up at the other end. i can't believe this all worked!!! (This used to be commit 2245b0c6d13c7c5886e81f9137b05df883598c26) --- source3/smbd/password.c | 501 ------------------------------------------------ 1 file changed, 501 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c14b50d3a6..240ec30c3f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -31,209 +31,6 @@ extern pstring scope; extern pstring global_myname; extern fstring global_myworkgroup; -/* Data to do lanman1/2 password challenge. */ -static unsigned char saved_challenge[8]; -static BOOL challenge_sent=False; - -/******************************************************************* -Get the next challenge value - no repeats. -********************************************************************/ -void generate_next_challenge(char *challenge) -{ -#if 0 - /* - * Leave this ifdef'd out while we test - * the new crypto random number generator. - * JRA. - */ - unsigned char buf[16]; - static int counter = 0; - struct timeval tval; - int v1,v2; - - /* get a sort-of random number */ - GetTimeOfDay(&tval); - v1 = (counter++) + getpid() + tval.tv_sec; - v2 = (counter++) * getpid() + tval.tv_usec; - SIVAL(challenge,0,v1); - SIVAL(challenge,4,v2); - - /* mash it up with md4 */ - mdfour(buf, (unsigned char *)challenge, 8); -#else - unsigned char buf[8]; - - generate_random_buffer(buf,8,False); -#endif - memcpy(saved_challenge, buf, 8); - memcpy(challenge,buf,8); - challenge_sent = True; -} - -/******************************************************************* -set the last challenge sent, usually from a password server -********************************************************************/ -BOOL set_challenge(unsigned char *challenge) -{ - memcpy(saved_challenge,challenge,8); - challenge_sent = True; - return(True); -} - -/******************************************************************* -get the last challenge sent -********************************************************************/ -static BOOL last_challenge(unsigned char *challenge) -{ - if (!challenge_sent) return False; - memcpy(challenge,saved_challenge,8); - return(True); -} - -/* this holds info on user ids that are already validated for this VC */ -static user_struct *validated_users = NULL; -static int num_validated_users = 0; - -/**************************************************************************** -check if a uid has been validated, and return an pointer to the user_struct -if it has. NULL if not. vuid is biased by an offset. This allows us to -tell random client vuid's (normally zero) from valid vuids. -****************************************************************************/ -user_struct *get_valid_user_struct(uint16 vuid) -{ - if (vuid == UID_FIELD_INVALID) - return NULL; - vuid -= VUID_OFFSET; - if ((vuid >= (uint16)num_validated_users) || - (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1)) - return NULL; - return &validated_users[vuid]; -} - -/**************************************************************************** -invalidate a uid -****************************************************************************/ -void invalidate_vuid(uint16 vuid) -{ - user_struct *vuser = get_valid_user_struct(vuid); - - if (vuser == NULL) return; - - vuser->uid = (uid_t)-1; - vuser->gid = (gid_t)-1; - - vuser->n_sids = 0; - - /* same number of igroups as groups */ - vuser->n_groups = 0; - - if (vuser->groups) - free((char *)vuser->groups); - - if (vuser->sids) - free((char *)vuser->sids); - - vuser->sids = NULL; - vuser->groups = NULL; -} - - -/**************************************************************************** -return a validated username -****************************************************************************/ -char *validated_username(uint16 vuid) -{ - user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) - return 0; - return(vuser->name); -} - - - -/**************************************************************************** -register a uid/name pair as being valid and that a valid password -has been given. vuid is biased by an offset. This allows us to -tell random client vuid's (normally zero) from valid vuids. -****************************************************************************/ -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest, uchar user_sess_key[16]) -{ - user_struct *vuser; - struct passwd *pwfile; /* for getting real name from passwd file */ - - /* Ensure no vuid gets registered in share level security. */ - if(lp_security() == SEC_SHARE) - return UID_FIELD_INVALID; - -#if 0 - /* - * After observing MS-Exchange services writing to a Samba share - * I belive this code is incorrect. Each service does its own - * sessionsetup_and_X for the same user, and as each service shuts - * down, it does a user_logoff_and_X. As we are consolidating multiple - * sessionsetup_and_X's onto the same vuid here, when the first service - * shuts down, it invalidates all the open files for the other services. - * Hence I am removing this code and forcing each sessionsetup_and_X - * to get a new vuid. - * Jeremy Allison. (jallison@whistle.com). - */ - - int i; - for(i = 0; i < num_validated_users; i++) { - vuser = &validated_users[i]; - if ( vuser->uid == uid ) - return (uint16)(i + VUID_OFFSET); /* User already validated */ - } -#endif - - validated_users = (user_struct *)Realloc(validated_users, - sizeof(user_struct)* - (num_validated_users+1)); - - if (!validated_users) - { - DEBUG(0,("Failed to realloc users struct!\n")); - num_validated_users = 0; - return UID_FIELD_INVALID; - } - - vuser = &validated_users[num_validated_users]; - num_validated_users++; - - vuser->uid = uid; - vuser->gid = gid; - vuser->guest = guest; - fstrcpy(vuser->name,unix_name); - fstrcpy(vuser->requested_name,requested_name); - memcpy(vuser->dc.user_sess_key, user_sess_key, sizeof(vuser->dc.user_sess_key)); - - vuser->n_sids = 0; - vuser->sids = NULL; - - vuser->n_groups = 0; - vuser->groups = NULL; - - /* Find all the groups this uid is in and store them. - Used by become_user() */ - get_unixgroups(unix_name,uid,gid, - &vuser->n_groups, - &vuser->groups); - - DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); - - DEBUG(3, ("Clearing default real name\n")); - fstrcpy(vuser->real_name, "\0"); - if (lp_unix_realname()) { - if ((pwfile=hashed_getpwnam(vuser->name))!= NULL) - { - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); - fstrcpy(vuser->real_name, pwfile->pw_gecos); - } - } - - return (uint16)((num_validated_users - 1) + VUID_OFFSET); -} - /**************************************************************************** add a name to the session users list @@ -290,275 +87,6 @@ static BOOL update_smbpassword_file(char *user, char *password) -/**************************************************************************** -core of smb password checking routine. -****************************************************************************/ -static BOOL smb_pwd_check_ntlmv1(char *password, unsigned char *part_passwd, - unsigned char *c8, - uchar sess_key[16]) -{ - /* Finish the encryption of part_passwd. */ - unsigned char p24[24]; - - if (part_passwd == NULL) - DEBUG(10,("No password set - allowing access\n")); - /* No password set - always true ! */ - if (part_passwd == NULL) - return True; - - SMBOWFencrypt(part_passwd, c8, p24); - if (sess_key != NULL) - { - SMBsesskeygen_ntv1(part_passwd, NULL, sess_key); - } - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |")); - dump_data(100, part_passwd, 16); - DEBUG(100,("Password from client was |")); - dump_data(100, password, 24); - DEBUG(100,("Given challenge was |")); - dump_data(100, c8, 8); - DEBUG(100,("Value from encryption was |")); - dump_data(100, p24, 24); -#endif - return (memcmp(p24, password, 24) == 0); -} - -/**************************************************************************** -core of smb password checking routine. -****************************************************************************/ -static BOOL smb_pwd_check_ntlmv2(char *password, size_t pwd_len, - unsigned char *part_passwd, - unsigned char const *c8, - const char *user, const char *domain, - char *sess_key) -{ - /* Finish the encryption of part_passwd. */ - unsigned char kr[16]; - unsigned char resp[16]; - - if (part_passwd == NULL) - { - DEBUG(10,("No password set - allowing access\n")); - } - /* No password set - always true ! */ - if (part_passwd == NULL) - { - return True; - } - - ntv2_owf_gen(part_passwd, user, domain, kr); - SMBOWFencrypt_ntv2(kr, c8, 8, password+16, pwd_len-16, resp); - if (sess_key != NULL) - { - SMBsesskeygen_ntv2(kr, resp, sess_key); - } - -#if DEBUG_PASSWORD - DEBUG(100,("Part password (P16) was |")); - dump_data(100, part_passwd, 16); - DEBUG(100,("Password from client was |")); - dump_data(100, password, pwd_len); - DEBUG(100,("Given challenge was |")); - dump_data(100, c8, 8); - DEBUG(100,("Value from encryption was |")); - dump_data(100, resp, 16); -#endif - - return (memcmp(resp, password, 16) == 0); -} - -/**************************************************************************** - Do a specific test for an smb password being correct, given a smb_password and - the lanman and NT responses. -****************************************************************************/ -BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], - const char *user, const char *domain, - uchar *lm_pass, size_t lm_pwd_len, - uchar *nt_pass, size_t nt_pwd_len, - uchar sess_key[16]) -{ - uchar challenge[8]; - - if (smb_pass == NULL) - { - return False; - } - - DEBUG(4,("Checking SMB password for user %s\n", - smb_pass->unix_name)); - - if (smb_pass->acct_ctrl & ACB_DISABLED) - { - DEBUG(3,("account for user %s was disabled.\n", - smb_pass->unix_name)); - return False; - } - - if (chal == NULL) - { - DEBUG(5,("use last SMBnegprot challenge\n")); - if (!last_challenge(challenge)) - { - DEBUG(1,("no challenge done - password failed\n")); - return False; - } - } - else - { - DEBUG(5,("challenge received\n")); - memcpy(challenge, chal, 8); - } - - if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) - { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - if (lp_server_ntlmv2() != False && nt_pwd_len > 24) - { - DEBUG(4,("smb_password_ok: Check NTLMv2 password\n")); - if (smb_pwd_check_ntlmv2(nt_pass, nt_pwd_len, - (uchar *)smb_pass->smb_nt_passwd, - challenge, user, domain, - sess_key)) - { - return True; - } - } - if (lp_server_ntlmv2() != True && nt_pwd_len == 24) - { - DEBUG(4,("smb_password_ok: Check NT MD4 password\n")); - if (smb_pwd_check_ntlmv1((char *)nt_pass, - (uchar *)smb_pass->smb_nt_passwd, - challenge, - sess_key)) - { - DEBUG(4,("NT MD4 password check succeeded\n")); - return True; - } - } - DEBUG(4,("NT MD4 password check failed\n")); - } - - if (lp_server_ntlmv2() == True) - { - DEBUG(4,("Not checking LM MD4 password\n")); - return False; - } - - /* Try against the lanman password. smb_pass->smb_passwd == NULL means - no password, allow access. */ - - DEBUG(4,("Checking LM MD4 password\n")); - - if ((smb_pass->smb_passwd == NULL) && - (smb_pass->acct_ctrl & ACB_PWNOTREQ)) - { - DEBUG(4,("no password required for user %s\n", - smb_pass->unix_name)); - return True; - } - - if ((smb_pass->smb_passwd != NULL) && - smb_pwd_check_ntlmv1((char *)lm_pass, - (uchar *)smb_pass->smb_passwd, - challenge, NULL)) - { - DEBUG(4,("LM MD4 password check succeeded\n")); - return(True); - } - - DEBUG(4,("LM MD4 password check failed\n")); - - return False; -} - - -/**************************************************************************** -check if a username/password is OK assuming the password is a 24 byte -SMB hash -return True if the password is correct, False otherwise -****************************************************************************/ - -BOOL pass_check_smb(struct smb_passwd *smb_pass, char *domain, uchar *chal, - uchar *lm_pwd, size_t lm_pwd_len, - uchar *nt_pwd, size_t nt_pwd_len, - struct passwd *pwd, uchar user_sess_key[16]) -{ - const struct passwd *pass; - struct passwd pw; - char *user = NULL; - - if (smb_pass == NULL) - { - DEBUG(3,("Couldn't find user %s in smb_passwd file.\n", user)); - return False; - } - - user = smb_pass->unix_name; - - if (lm_pwd == NULL || nt_pwd == NULL) - { - return False; - } - - if (pwd != NULL && user == NULL) - { - pass = (struct passwd *) pwd; - user = pass->pw_name; - } - else - { - pass = Get_Pwnam(user,True); - if (pass == NULL) - { - DEBUG(3,("Couldn't find user %s\n",user)); - return False; - } - memcpy(&pw, pass, sizeof(struct passwd)); - pass = &pw; - } - - /* Quit if the account was disabled. */ - if (smb_pass->acct_ctrl & ACB_DISABLED) { - DEBUG(3,("account for user %s was disabled.\n", user)); - return False; - } - - /* Ensure the uid's match */ - if (smb_pass->unix_uid != pass->pw_uid) - { - DEBUG(3,("Error : UNIX (%d) and SMB (%d) uids in password files do not match !\n", pass->pw_uid, smb_pass->unix_uid)); - return False; - } - - if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords()) - { - DEBUG(3,("account for user %s has no password and null passwords are allowed.\n", smb_pass->unix_name)); - return(True); - } - - if (smb_password_ok(smb_pass, chal, user, domain, - lm_pwd, lm_pwd_len, - nt_pwd, nt_pwd_len, - user_sess_key)) - { - if (user_sess_key != NULL) - { -#ifdef DEBUG_PASSWORD - DEBUG(100,("user session key: ")); - dump_data(100, user_sess_key, 16); -#endif - } - return(True); - } - - DEBUG(3,("Error pass_check_smb failed\n")); - return False; -} - /**************************************************************************** check if a username/password pair is OK either via the system password database or the encrypted SMB password database @@ -589,35 +117,6 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, update_smbpassword_file : NULL); } -/**************************************************************************** -check if a username is valid -****************************************************************************/ -BOOL user_ok(char *user,int snum) -{ - pstring valid, invalid; - BOOL ret; - - StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)); - StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)); - - string_sub(valid,"%S",lp_servicename(snum)); - string_sub(invalid,"%S",lp_servicename(snum)); - - ret = !user_in_list(user,invalid); - - if (ret && valid && *valid) { - ret = user_in_list(user,valid); - } - - if (ret && lp_onlyuser(snum)) { - char *user_list = lp_username(snum); - string_sub(user_list,"%S",lp_servicename(snum)); - ret = user_in_list(user,user_list); - } - - return(ret); -} - -- cgit From 0ce128e3550794d4dbbd1def00e87c020f72c992 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 01:25:49 +0000 Subject: delineation between smb and msrpc more marked. smbd now constructs pdus, and then feeds them over either a "local" function call or a "remote" function call to an msrpc service. the "remote" msrpc daemon, on the other side of a unix socket, then calls the same "local" function that smbd would, if the msrpc service were being run from inside smbd. this allows a transition from local msrpc services (inside the same smbd process) to remote (over a unix socket). removed reference to pipes_struct in msrpc services. all msrpc processing functions take rpcsrv_struct which is a structure containing state info for the msrpc functions to decode and create pdus. created become_vuser() which does everything not related to connection_struct that become_user() does. removed, as best i could, connection_struct dependencies from the nt spoolss printing code. todo: remove dcinfo from rpcsrv_struct because this stores NETLOGON-specific info on a per-connection basis, and if the connection dies then so does the info, and that's a fairly serious problem. had to put pretty much everything that is in user_struct into parse_creds.c to feed unix user info over to the msrpc daemons. why? because it's expensive to do unix password/group database lookups, and it's definitely expensive to do nt user profile lookups, not to mention pretty difficult and if you did either of these it would introduce a complication / unnecessary interdependency. so, send uid/gid/num_groups/gid_t* + SID+num_rids+domain_group_rids* + unix username + nt username + nt domain + user session key etc. this is the MINIMUM info identified so far that's actually implemented. missing bits include the called and calling netbios names etc. (basically, anything that can be loaded into standard_sub() and standard_sub_basic()...) (This used to be commit aa3c659a8dba0437c17c60055a6ed30fdfecdb6d) --- source3/smbd/password.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 240ec30c3f..91f727701c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -221,14 +221,14 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL, vuser->dc.user_sess_key); + ok = password_ok(user,password, pwlen, NULL, vuser->user_sess_key); if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); } /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->name,snum) && - password_ok(vuser->name, password, pwlen, NULL, vuser->dc.user_sess_key)) { + password_ok(vuser->name, password, pwlen, NULL, vuser->user_sess_key)) { fstrcpy(user, vuser->name); vuser->guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); @@ -252,7 +252,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstrcpy(user2,auser); if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen, NULL, vuser->dc.user_sess_key)) { + if (password_ok(user2,password, pwlen, NULL, vuser->user_sess_key)) { ok = True; fstrcpy(user,user2); DEBUG(3,("ACCEPTED: session list username and given password ok\n")); @@ -291,7 +291,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, { if (*auser == '@') { - auser = validate_group(auser+1,password,pwlen,snum, vuser->dc.user_sess_key); + auser = validate_group(auser+1,password,pwlen,snum, vuser->user_sess_key); if (auser) { ok = True; @@ -304,7 +304,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstring user2; fstrcpy(user2,auser); if (user_ok(user2,snum) && - password_ok(user2,password,pwlen,NULL, vuser->dc.user_sess_key)) + password_ok(user2,password,pwlen,NULL, vuser->user_sess_key)) { ok = True; fstrcpy(user,user2); -- cgit From 4f8a24522c683761c6f2ee23dba56f6c7913377b Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 20:03:42 +0000 Subject: final part of "first" phase converting over to msrpc daemon architecture. done a minimal amout of clean-up in the Makefile, removing unnecessary modules from the link stage. this is not complete, yet, and will involve some changes, for example to smbd, to remove dependencies on the password database API that shouldn't be there. for example, smbd should not ever call getsmbpwXXX() it should call the Samr or Lsa API. this first implementation has minor problems with not reinstantiating the same services as the caller. the "homes" service is a good example. (This used to be commit caa50525220b0d0250fa139367593c2de2c12135) --- source3/smbd/password.c | 129 ------------------------------------------------ 1 file changed, 129 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 91f727701c..fa46a74c14 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -606,132 +606,3 @@ use this machine as the password server.\n")); return(True); } -/*********************************************************************** - Do the same as security=server, but using NT Domain calls and a session - key from the workstation trust account password. -************************************************************************/ - -BOOL domain_client_validate( char *user, char *domain, - char *acct_name, uint16 acct_type, - char *smb_apasswd, int smb_apasslen, - char *smb_ntpasswd, int smb_ntpasslen, - uchar user_sess_key[16]) -{ - unsigned char local_challenge[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_reponse[24]; - unsigned char trust_passwd[16]; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 info3; - uint32 smb_uid_low; - fstring trust_acct; - fstring srv_name; - - fstrcpy(trust_acct, acct_name); - fstrcat(trust_acct, "$"); - - /* - * Check that the requested domain is not our own machine name. - * If it is, we should never check the PDC here, we use our own local - * password file. - */ - - if(strequal( domain, global_myname)) - { - DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); - return False; - } - - if (!get_any_dc_name(domain, srv_name)) - { - DEBUG(3,("domain_client_validate: could not find domain %s\n", - domain)); - return False; - } - - /* - * Next, check that the passwords given were encrypted. - */ - - if(((smb_apasslen != 24) && (smb_apasslen != 0)) || - ((smb_ntpasslen <= 24) && (smb_ntpasslen != 0))) - { - /* - * Not encrypted - do so. - */ - - DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); - generate_random_buffer( local_challenge, 8, False); - SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); - SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse); - smb_apasslen = 24; - smb_ntpasslen = 24; - smb_apasswd = (char *)local_lm_response; - smb_ntpasswd = (char *)local_nt_reponse; - } - else - { - /* - * Encrypted - get the challenge we sent for these - * responses. - */ - - if (!last_challenge(local_challenge)) - { - DEBUG(0,("domain_client_validate: no challenge done - password failed\n")); - return False; - } - } - - /* - * Get the workstation trust account password. - */ - if (!trust_get_passwd( trust_passwd, domain, acct_name)) - { - return False; - } - - /* - * At this point, smb_apasswd points to the lanman response to - * the challenge in local_challenge, and smb_ntpasswd points to - * the NT response to the challenge in local_challenge. Ship - * these over the secure channel to a domain controller and - * see if they were valid. - */ - - /* - * Ok - we have an anonymous connection to the IPC$ share. - * Now start the NT Domain stuff :-). - */ - - if(cli_nt_setup_creds(srv_name, global_myname, trust_acct, - trust_passwd, acct_type) != 0x0) - { - DEBUG(0,("domain_client_validate: unable to setup the PDC credentials to machine \ - %s.\n", srv_name)); - return False; - } - - /* We really don't care what LUID we give the user. */ - generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - - if (!cli_nt_login_network(srv_name, global_myname, - domain, user, - smb_uid_low, (char *)local_challenge, - ((smb_apasslen != 0) ? smb_apasswd : NULL), - ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), - &ctr, &info3)) - { - DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ - %s to Domain controller %s.\n", user, domain, srv_name)); - return False; - } - - /* - * Here, if we really want it, we have lots of info about the user in info3. - * LKCLXXXX - really important to check things like "is this user acct - * locked out / disabled" etc!!!! - */ - - return True; -} -- cgit From f6276724bafdb6145c0c7b565172d80cb04516ea Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Sun, 12 Dec 1999 21:00:35 +0000 Subject: changed function name of get_home_dir() to get_unixhome_dir(), to stop clash with gnu readline library. fixed issue with [homes] service not being there - call lp_add_home() just before starting the msrpc processing. (This used to be commit 054195df9b6187c663ede5cf4489499abbdc29fc) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fa46a74c14..e15e08a1af 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -470,7 +470,7 @@ BOOL check_hosts_equiv(char *user) if (lp_use_rhosts()) { - char *home = get_home_dir(user); + char *home = get_unixhome_dir(user); if (home) { extern int Client; slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); -- cgit From 3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 13 Dec 1999 13:27:58 +0000 Subject: first pass at updating head branch to be to be the same as the SAMBA_2_0 branch (This used to be commit 453a822a76780063dff23526c35408866d0c0154) --- source3/smbd/password.c | 1042 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 954 insertions(+), 88 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e15e08a1af..9792c9ebc8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -23,6 +23,7 @@ extern int DEBUGLEVEL; extern int Protocol; +extern struct in_addr ipzero; /* users from session setup */ static pstring session_users=""; @@ -31,6 +32,261 @@ extern pstring scope; extern pstring global_myname; extern fstring global_myworkgroup; +/* Data to do lanman1/2 password challenge. */ +static unsigned char saved_challenge[8]; +static BOOL challenge_sent=False; + +/******************************************************************* +Get the next challenge value - no repeats. +********************************************************************/ +void generate_next_challenge(char *challenge) +{ +#if 0 + /* + * Leave this ifdef'd out while we test + * the new crypto random number generator. + * JRA. + */ + unsigned char buf[16]; + static int counter = 0; + struct timeval tval; + int v1,v2; + + /* get a sort-of random number */ + GetTimeOfDay(&tval); + v1 = (counter++) + getpid() + tval.tv_sec; + v2 = (counter++) * getpid() + tval.tv_usec; + SIVAL(challenge,0,v1); + SIVAL(challenge,4,v2); + + /* mash it up with md4 */ + mdfour(buf, (unsigned char *)challenge, 8); +#else + unsigned char buf[8]; + + generate_random_buffer(buf,8,False); +#endif + memcpy(saved_challenge, buf, 8); + memcpy(challenge,buf,8); + challenge_sent = True; +} + +/******************************************************************* +set the last challenge sent, usually from a password server +********************************************************************/ +BOOL set_challenge(unsigned char *challenge) +{ + memcpy(saved_challenge,challenge,8); + challenge_sent = True; + return(True); +} + +/******************************************************************* +get the last challenge sent +********************************************************************/ +static BOOL last_challenge(unsigned char *challenge) +{ + if (!challenge_sent) return(False); + memcpy(challenge,saved_challenge,8); + return(True); +} + +/* this holds info on user ids that are already validated for this VC */ +static user_struct *validated_users = NULL; +static int num_validated_users = 0; + +/**************************************************************************** +check if a uid has been validated, and return an pointer to the user_struct +if it has. NULL if not. vuid is biased by an offset. This allows us to +tell random client vuid's (normally zero) from valid vuids. +****************************************************************************/ +user_struct *get_valid_user_struct(uint16 vuid) +{ + if (vuid == UID_FIELD_INVALID) + return NULL; + vuid -= VUID_OFFSET; + if ((vuid >= (uint16)num_validated_users) || + (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1)) + return NULL; + return &validated_users[vuid]; +} + +/**************************************************************************** +invalidate a uid +****************************************************************************/ +void invalidate_vuid(uint16 vuid) +{ + user_struct *vuser = get_valid_user_struct(vuid); + + if (vuser == NULL) return; + + vuser->uid = (uid_t)-1; + vuser->gid = (gid_t)-1; + + vuser->n_sids = 0; + + /* same number of igroups as groups */ + vuser->n_groups = 0; + + if (vuser->groups) + free((char *)vuser->groups); + + if (vuser->sids) + free((char *)vuser->sids); + + vuser->sids = NULL; + vuser->groups = NULL; +} + + +/**************************************************************************** +return a validated username +****************************************************************************/ +char *validated_username(uint16 vuid) +{ + user_struct *vuser = get_valid_user_struct(vuid); + if (vuser == NULL) + return 0; + return(vuser->name); +} + + +/**************************************************************************** +Setup the groups a user belongs to. +****************************************************************************/ +int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) +{ + int i,ngroups; + gid_t grp = 0; + gid_t *groups = NULL; + + if (-1 == initgroups(user,gid)) + { + DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); + if (getuid() == 0) + { + if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) + { + DEBUG(0,("This is probably a problem with the account %s\n", user)); + } + } + return -1; + } + + ngroups = sys_getgroups(0,&grp); + if (ngroups <= 0) + { + ngroups = 32; + } + +#ifdef NGROUPS_MAX + if((groups = (gid_t *)malloc(sizeof(gid_t)*NGROUPS_MAX)) == NULL) +#else /* NGROUPS_MAX */ + if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) +#endif /* NGROUPS_MAX */ + { + DEBUG(0,("setup_groups malloc fail !\n")); + return -1; + } + + ngroups = sys_getgroups(ngroups,groups); + + (*p_ngroups) = ngroups; + (*p_groups) = groups; + + DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) ); + for (i = 0; i < ngroups; i++ ) + { + DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) ); + } + DEBUG( 3, ( "\n" ) ); + + return 0; +} + + +/**************************************************************************** +register a uid/name pair as being valid and that a valid password +has been given. vuid is biased by an offset. This allows us to +tell random client vuid's (normally zero) from valid vuids. +****************************************************************************/ +uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest) +{ + user_struct *vuser; + struct passwd *pwfile; /* for getting real name from passwd file */ + + /* Ensure no vuid gets registered in share level security. */ + if(lp_security() == SEC_SHARE) + return UID_FIELD_INVALID; + +#if 0 + /* + * After observing MS-Exchange services writing to a Samba share + * I belive this code is incorrect. Each service does its own + * sessionsetup_and_X for the same user, and as each service shuts + * down, it does a user_logoff_and_X. As we are consolidating multiple + * sessionsetup_and_X's onto the same vuid here, when the first service + * shuts down, it invalidates all the open files for the other services. + * Hence I am removing this code and forcing each sessionsetup_and_X + * to get a new vuid. + * Jeremy Allison. (jallison@whistle.com). + */ + + int i; + for(i = 0; i < num_validated_users; i++) { + vuser = &validated_users[i]; + if ( vuser->uid == uid ) + return (uint16)(i + VUID_OFFSET); /* User already validated */ + } +#endif + + validated_users = (user_struct *)Realloc(validated_users, + sizeof(user_struct)* + (num_validated_users+1)); + + if (!validated_users) + { + DEBUG(0,("Failed to realloc users struct!\n")); + num_validated_users = 0; + return UID_FIELD_INVALID; + } + + vuser = &validated_users[num_validated_users]; + num_validated_users++; + + vuser->uid = uid; + vuser->gid = gid; + vuser->guest = guest; + fstrcpy(vuser->name,unix_name); + fstrcpy(vuser->requested_name,requested_name); + + vuser->n_sids = 0; + vuser->sids = NULL; + + vuser->n_groups = 0; + vuser->groups = NULL; + + /* Find all the groups this uid is in and store them. + Used by become_user() */ + setup_groups(unix_name,uid,gid, + &vuser->n_groups, + &vuser->groups); + + DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); + + DEBUG(3, ("Clearing default real name\n")); + fstrcpy(vuser->real_name, "\0"); + if (lp_unix_realname()) { + if ((pwfile=sys_getpwnam(vuser->name))!= NULL) + { + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); + fstrcpy(vuser->real_name, pwfile->pw_gecos); + } + } + + return (uint16)((num_validated_users - 1) + VUID_OFFSET); +} + /**************************************************************************** add a name to the session users list @@ -71,12 +327,17 @@ static BOOL update_smbpassword_file(char *user, char *password) DEBUG(0,("getsmbpwnam returned NULL\n")); return False; } - + + /* + * Remove the account disabled flag - we are updating the + * users password from a login. + */ + smbpw->acct_ctrl &= ~ACB_DISABLED; + /* Here, the flag is one, because we want to ignore the XXXXXXX'd out password */ ret = change_oem_password( smbpw, password, True); - if (!ret) - { + if (ret == False) { DEBUG(3,("change_oem_password returned False\n")); } @@ -87,17 +348,202 @@ static BOOL update_smbpassword_file(char *user, char *password) +/**************************************************************************** +core of smb password checking routine. +****************************************************************************/ +BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8) +{ + /* Finish the encryption of part_passwd. */ + unsigned char p21[21]; + unsigned char p24[24]; + + if (part_passwd == NULL) + DEBUG(10,("No password set - allowing access\n")); + /* No password set - always true ! */ + if (part_passwd == NULL) + return 1; + + memset(p21,'\0',21); + memcpy(p21,part_passwd,16); + E_P24(p21, c8, p24); +#if DEBUG_PASSWORD + { + int i; + DEBUG(100,("Part password (P16) was |")); + for(i = 0; i < 16; i++) + DEBUG(100,("%X ", (unsigned char)part_passwd[i])); + DEBUG(100,("|\n")); + DEBUG(100,("Password from client was |")); + for(i = 0; i < 24; i++) + DEBUG(100,("%X ", (unsigned char)password[i])); + DEBUG(100,("|\n")); + DEBUG(100,("Given challenge was |")); + for(i = 0; i < 8; i++) + DEBUG(100,("%X ", (unsigned char)c8[i])); + DEBUG(100,("|\n")); + DEBUG(100,("Value from encryption was |")); + for(i = 0; i < 24; i++) + DEBUG(100,("%X ", (unsigned char)p24[i])); + DEBUG(100,("|\n")); + } +#endif + return (memcmp(p24, password, 24) == 0); +} + +/**************************************************************************** + Do a specific test for an smb password being correct, given a smb_password and + the lanman and NT responses. +****************************************************************************/ +BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], + uchar lm_pass[24], uchar nt_pass[24]) +{ + uchar challenge[8]; + + if (!lm_pass || !smb_pass) return(False); + + DEBUG(4,("Checking SMB password for user %s\n", + smb_pass->smb_name)); + + if(smb_pass->acct_ctrl & ACB_DISABLED) { + DEBUG(1,("account for user %s was disabled.\n", + smb_pass->smb_name)); + return(False); + } + + if (chal == NULL) + { + DEBUG(5,("use last SMBnegprot challenge\n")); + if (!last_challenge(challenge)) + { + DEBUG(1,("no challenge done - password failed\n")); + return False; + } + } + else + { + DEBUG(5,("challenge received\n")); + memcpy(challenge, chal, 8); + } + + if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) { + /* We have the NT MD4 hash challenge available - see if we can + use it (ie. does it exist in the smbpasswd file). + */ + DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); + if (smb_password_check((char *)nt_pass, + (uchar *)smb_pass->smb_nt_passwd, + challenge)) { + DEBUG(4,("NT MD4 password check succeeded\n")); + return(True); + } + DEBUG(4,("NT MD4 password check failed\n")); + } + + /* Try against the lanman password. smb_pass->smb_passwd == NULL means + no password, allow access. */ + + DEBUG(4,("Checking LM MD4 password\n")); + + if((smb_pass->smb_passwd == NULL) && + (smb_pass->acct_ctrl & ACB_PWNOTREQ)) { + DEBUG(4,("no password required for user %s\n", + smb_pass->smb_name)); + return True; + } + + if((smb_pass->smb_passwd != NULL) && + smb_password_check((char *)lm_pass, + (uchar *)smb_pass->smb_passwd, challenge)) { + DEBUG(4,("LM MD4 password check succeeded\n")); + return(True); + } + + DEBUG(4,("LM MD4 password check failed\n")); + + return False; +} + + +/**************************************************************************** +check if a username/password is OK assuming the password is a 24 byte +SMB hash +return True if the password is correct, False otherwise +****************************************************************************/ + +BOOL pass_check_smb(char *user, char *domain, + uchar *chal, uchar *lm_pwd, uchar *nt_pwd, + struct passwd *pwd) +{ + struct passwd *pass; + struct smb_passwd *smb_pass; + + if (!lm_pwd || !nt_pwd) + { + return(False); + } + + if (pwd != NULL && user == NULL) + { + pass = (struct passwd *) pwd; + user = pass->pw_name; + } + else + { + pass = Get_Pwnam(user,True); + } + + if (pass == NULL) + { + DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",user)); + return(False); + } + + smb_pass = getsmbpwnam(user); + + if (smb_pass == NULL) + { + DEBUG(1,("Couldn't find user '%s' in smb_passwd file.\n", user)); + return(False); + } + + /* Quit if the account was disabled. */ + if(smb_pass->acct_ctrl & ACB_DISABLED) { + DEBUG(1,("Account for user '%s' was disabled.\n", user)); + return(False); + } + + /* Ensure the uid's match */ + if (smb_pass->smb_userid != pass->pw_uid) + { + DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user)); + return(False); + } + + if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords()) + { + DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name)); + return(True); + } + + if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd)) + { + return(True); + } + + DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user)); + return False; +} + /**************************************************************************** check if a username/password pair is OK either via the system password database or the encrypted SMB password database return True if the password is correct, False otherwise ****************************************************************************/ -BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, - uchar user_sess_key[16]) +BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) { - if (pwlen >= 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) + if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { - /* if 24 bytes or longer assume it is an encrypted password */ + /* if 24 bytes long assume it is an encrypted password */ uchar challenge[8]; if (!last_challenge(challenge)) @@ -106,10 +552,8 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, return False; } - return pass_check_smb(getsmbpwnam(user), global_myworkgroup, - challenge, (uchar *)password, - pwlen, (uchar *)password, pwlen, - pwd, user_sess_key); + return pass_check_smb(user, global_myworkgroup, + challenge, (uchar *)password, (uchar *)password, pwd); } return pass_check(user, password, pwlen, pwd, @@ -117,71 +561,84 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd, update_smbpassword_file : NULL); } +/**************************************************************************** +check if a username is valid +****************************************************************************/ +BOOL user_ok(char *user,int snum) +{ + pstring valid, invalid; + BOOL ret; + + StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)-1); + StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)-1); + + pstring_sub(valid,"%S",lp_servicename(snum)); + pstring_sub(invalid,"%S",lp_servicename(snum)); + + ret = !user_in_list(user,invalid); + + if (ret && valid && *valid) { + ret = user_in_list(user,valid); + } + + if (ret && lp_onlyuser(snum)) { + char *user_list = lp_username(snum); + pstring_sub(user_list,"%S",lp_servicename(snum)); + ret = user_in_list(user,user_list); + } + + return(ret); +} + /**************************************************************************** validate a group username entry. Return the username or NULL ****************************************************************************/ -static char *validate_group(char *group,char *password,int pwlen,int snum, - uchar user_sess_key[16]) +static char *validate_group(char *group,char *password,int pwlen,int snum) { -#if defined(HAVE_NETGROUP) && defined(HAVE_GETNETGRENT) && defined(HAVE_SETNETGRENT) && defined(HAVE_ENDNETGRENT) - { - char *host, *user, *domain; - setnetgrent(group); - while (getnetgrent(&host, &user, &domain)) { - if (user) { - if (user_ok(user, snum) && - password_ok(user,password,pwlen,NULL, user_sess_key)) { - endnetgrent(); - return(user); +#ifdef HAVE_NETGROUP + { + char *host, *user, *domain; + setnetgrent(group); + while (getnetgrent(&host, &user, &domain)) { + if (user) { + if (user_ok(user, snum) && + password_ok(user,password,pwlen,NULL)) { + endnetgrent(); + return(user); + } + } + } + endnetgrent(); } - } - } - endnetgrent(); - } #endif -#ifdef HAVE_GETGRNAM - { - struct group *gptr = (struct group *)getgrnam(group); - char **member; - if (gptr) - { - member = gptr->gr_mem; - while (member && *member) - { - static fstring name; - fstrcpy(name,*member); - if (user_ok(name,snum) && - password_ok(name,password,pwlen,NULL, user_sess_key)) - return(&name[0]); - member++; - } -#ifdef GROUP_CHECK_PWENT +#ifdef HAVE_GETGRENT { - struct passwd *pwd; - static fstring tm; - - setpwent (); - while (pwd = getpwent ()) { - if (*(pwd->pw_passwd) && pwd->pw_gid == gptr->gr_gid) { - /* This Entry have PASSWORD and same GID then check pwd */ - if (password_ok(NULL, password, pwlen, pwd, user_sess_key)) { - fstrcpy(tm, pwd->pw_name); - endpwent (); - return tm; - } - } - } - endpwent (); + struct group *gptr; + char **member; + setgrent(); + while ((gptr = (struct group *)getgrent())) { + if (!strequal(gptr->gr_name,group)) + continue; + member = gptr->gr_mem; + while (member && *member) { + static fstring name; + fstrcpy(name,*member); + if (user_ok(name,snum) && + password_ok(name,password,pwlen,NULL)) { + endgrent(); + return(&name[0]); + } + member++; + } + } + endgrent(); } -#endif /* GROUP_CHECK_PWENT */ - } - } #endif - return(NULL); + return(NULL); } @@ -221,14 +678,14 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL, vuser->user_sess_key); + ok = password_ok(user,password, pwlen, NULL); if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); } /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->name,snum) && - password_ok(vuser->name, password, pwlen, NULL, vuser->user_sess_key)) { + password_ok(vuser->name, password, pwlen, NULL)) { fstrcpy(user, vuser->name); vuser->guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); @@ -242,7 +699,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, { char *auser; char *user_list = strdup(session_users); - if (!user_list) return False; + if (!user_list) return(False); for (auser=strtok(user_list,LIST_SEP); !ok && auser; @@ -252,7 +709,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstrcpy(user2,auser); if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen, NULL, vuser->user_sess_key)) { + if (password_ok(user2,password, pwlen, NULL)) { ok = True; fstrcpy(user,user2); DEBUG(3,("ACCEPTED: session list username and given password ok\n")); @@ -283,7 +740,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, pstring user_list; StrnCpy(user_list,lp_username(snum),sizeof(pstring)); - string_sub(user_list,"%S",lp_servicename(snum)); + pstring_sub(user_list,"%S",lp_servicename(snum)); for (auser=strtok(user_list,LIST_SEP); auser && !ok; @@ -291,7 +748,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, { if (*auser == '@') { - auser = validate_group(auser+1,password,pwlen,snum, vuser->user_sess_key); + auser = validate_group(auser+1,password,pwlen,snum); if (auser) { ok = True; @@ -304,7 +761,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, fstring user2; fstrcpy(user2,auser); if (user_ok(user2,snum) && - password_ok(user2,password,pwlen,NULL, vuser->user_sess_key)) + password_ok(user2,password,pwlen,NULL)) { ok = True; fstrcpy(user,user2); @@ -454,10 +911,10 @@ BOOL check_hosts_equiv(char *user) { char *fname = NULL; pstring rhostsfile; - const struct passwd *pass = Get_Pwnam(user,True); + struct passwd *pass = Get_Pwnam(user,True); if (!pass) - return False; + return(False); fname = lp_hosts_equiv(); @@ -470,7 +927,7 @@ BOOL check_hosts_equiv(char *user) if (lp_use_rhosts()) { - char *home = get_unixhome_dir(user); + char *home = get_user_home_dir(user); if (home) { extern int Client; slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); @@ -479,13 +936,14 @@ BOOL check_hosts_equiv(char *user) } } - return False; + return(False); } /**************************************************************************** -return the client state structure + Return the client state structure. ****************************************************************************/ + struct cli_state *server_client(void) { static struct cli_state pw_cli; @@ -493,20 +951,77 @@ struct cli_state *server_client(void) } /**************************************************************************** -support for server level security + Support for server level security. ****************************************************************************/ + struct cli_state *server_cryptkey(void) { - if (cli_connect_serverlist(server_client(), lp_passwordserver())) - { - return server_client(); + struct cli_state *cli; + fstring desthost; + struct in_addr dest_ip; + char *p; + BOOL connected_ok = False; + + cli = server_client(); + + if (!cli_initialise(cli)) + return NULL; + + p = lp_passwordserver(); + while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { + standard_sub_basic(desthost); + strupper(desthost); + + if(!resolve_name( desthost, &dest_ip, 0x20)) { + DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); + continue; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); + continue; + } + + if (cli_connect(cli, desthost, &dest_ip)) { + DEBUG(3,("connected to password server %s\n",desthost)); + connected_ok = True; + break; + } + } + + if (!connected_ok) { + DEBUG(0,("password server not available\n")); + cli_shutdown(cli); + return NULL; } - return NULL; + + if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip)) + return NULL; + + DEBUG(3,("got session\n")); + + if (!cli_negprot(cli)) { + DEBUG(1,("%s rejected the negprot\n",desthost)); + cli_shutdown(cli); + return NULL; + } + + if (cli->protocol < PROTOCOL_LANMAN2 || + !(cli->sec_mode & 1)) { + DEBUG(1,("%s isn't in user level security mode\n",desthost)); + cli_shutdown(cli); + return NULL; + } + + DEBUG(3,("password server OK\n")); + + return cli; } /**************************************************************************** -validate a password with the password server + Validate a password with the password server. ****************************************************************************/ + BOOL server_validate(char *user, char *domain, char *pass, int passlen, char *ntpass, int ntpasslen) @@ -520,7 +1035,7 @@ BOOL server_validate(char *user, char *domain, if (!cli->initialised) { DEBUG(1,("password server %s is not connected\n", cli->desthost)); - return False; + return(False); } if(badpass[0] == 0) @@ -541,8 +1056,7 @@ BOOL server_validate(char *user, char *domain, */ if(!tested_password_server) { - if (cli_session_setup(cli, global_myname, - user, (char *)badpass, sizeof(badpass), + if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), (char *)badpass, sizeof(badpass), domain)) { /* @@ -587,8 +1101,7 @@ use this machine as the password server.\n")); * not guest enabled, we can try with the real password. */ - if (!cli_session_setup(cli, global_myname, - user, pass, passlen, ntpass, ntpasslen, domain)) { + if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { DEBUG(1,("password server %s rejected the password\n", cli->desthost)); return False; } @@ -597,12 +1110,365 @@ use this machine as the password server.\n")); if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); cli_ulogoff(cli); - return False; + return(False); } - cli_ulogoff(cli); return(True); } +/*********************************************************************** + Connect to a remote machine for domain security authentication + given a name or IP address. +************************************************************************/ + +static BOOL connect_to_domain_password_server(struct cli_state *pcli, char *remote_machine, + unsigned char *trust_passwd) +{ + struct in_addr dest_ip; + + if(cli_initialise(pcli) == False) { + DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); + return False; + } + + standard_sub_basic(remote_machine); + strupper(remote_machine); + + if(!resolve_name( remote_machine, &dest_ip, 0x20)) { + DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (ismyip(dest_ip)) { + DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (!cli_connect(pcli, remote_machine, &dest_ip)) { + DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) { + DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \ +session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + return False; + } + + pcli->protocol = PROTOCOL_NT1; + + if (!cli_negprot(pcli)) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (pcli->protocol != PROTOCOL_NT1) { + DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + /* + * Do an anonymous session setup. + */ + + if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + if (!(pcli->sec_mode & 1)) { + DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n", + remote_machine)); + cli_shutdown(pcli); + return False; + } + + if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) { + DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \ +Error was : %s.\n", remote_machine, cli_errstr(pcli) )); + cli_shutdown(pcli); + return False; + } + + /* + * We now have an anonymous connection to IPC$ on the domain password server. + */ + + /* + * Even if the connect succeeds we need to setup the netlogon + * pipe here. We do this as we may just have changed the domain + * account password on the PDC and yet we may be talking to + * a BDC that doesn't have this replicated yet. In this case + * a successful connect to a DC needs to take the netlogon connect + * into account also. This patch from "Bjart Kvarme" . + */ + + if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) { + DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ +machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); + cli_nt_session_close(pcli); + cli_ulogoff(pcli); + cli_shutdown(pcli); + return False; + } + + if (cli_nt_setup_creds(pcli, trust_passwd) == False) { + DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ +%s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); + cli_nt_session_close(pcli); + cli_ulogoff(pcli); + cli_shutdown(pcli); + return(False); + } + + return True; +} + +/*********************************************************************** + Utility function to attempt a connection to an IP address of a DC. +************************************************************************/ + +static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, unsigned char *trust_passwd) +{ + fstring dc_name; + + /* + * Ignore addresses we have already tried. + */ + + if(ip_equal(ipzero, *ip)) + return False; + + if(!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) + return False; + + return connect_to_domain_password_server(pcli, dc_name, trust_passwd); +} + +/*********************************************************************** + Do the same as security=server, but using NT Domain calls and a session + key from the machine password. +************************************************************************/ + +BOOL domain_client_validate( char *user, char *domain, + char *smb_apasswd, int smb_apasslen, + char *smb_ntpasswd, int smb_ntpasslen, + BOOL *user_exists) +{ + unsigned char local_challenge[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_reponse[24]; + unsigned char trust_passwd[16]; + fstring remote_machine; + char *p; + NET_ID_INFO_CTR ctr; + NET_USER_INFO_3 info3; + struct cli_state cli; + uint32 smb_uid_low; + BOOL connected_ok = False; + + if(user_exists != NULL) + *user_exists = True; /* Only set false on a very specific error. */ + + /* + * Check that the requested domain is not our own machine name. + * If it is, we should never check the PDC here, we use our own local + * password file. + */ + + if(strequal( domain, global_myname)) { + DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); + return False; + } + + /* + * Next, check that the passwords given were encrypted. + */ + + if(((smb_apasslen != 24) && (smb_apasslen != 0)) || + ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) { + + /* + * Not encrypted - do so. + */ + + DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); + generate_random_buffer( local_challenge, 8, False); + SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); + SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse); + smb_apasslen = 24; + smb_ntpasslen = 24; + smb_apasswd = (char *)local_lm_response; + smb_ntpasswd = (char *)local_nt_reponse; + } else { + + /* + * Encrypted - get the challenge we sent for these + * responses. + */ + + if (!last_challenge(local_challenge)) { + DEBUG(0,("domain_client_validate: no challenge done - password failed\n")); + return False; + } + } + + /* + * Get the machine account password. + */ + if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) + { + return False; + } + + /* + * At this point, smb_apasswd points to the lanman response to + * the challenge in local_challenge, and smb_ntpasswd points to + * the NT response to the challenge in local_challenge. Ship + * these over the secure channel to a domain controller and + * see if they were valid. + */ + + ZERO_STRUCT(cli); + + /* + * Treat each name in the 'password server =' line as a potential + * PDC/BDC. Contact each in turn and try and authenticate. + */ + + p = lp_passwordserver(); + while(!connected_ok && p && + next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { + if(strequal(remote_machine, "*")) { + + /* + * We have been asked to dynamcially determine the IP addresses of + * the PDC and BDC's for this DOMAIN, and query them in turn. + */ + + struct in_addr *ip_list = NULL; + int count = 0; + int i; + + if(!get_dc_list(lp_workgroup(), &ip_list, &count)) + continue; + + /* + * Firstly try and contact a PDC/BDC who has the same + * network address as any of our interfaces. + */ + + for(i = 0; i < count; i++) { + if(!is_local_net(ip_list[i])) + continue; + + if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) + break; + + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Secondly try and contact a random PDC/BDC. + */ + + if(!connected_ok) { + i = (sys_random() % count); + + if(!(connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Finally go through the IP list in turn, ignoring any addresses + * we have already tried. + */ + + if(!connected_ok) { + + /* + * Try and connect to any of the other IP addresses in the PDC/BDC list. + * Note that from a WINS server the #1 IP address is the PDC. + */ + + for(i = 0; i < count; i++) { + if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) + break; + } + } + + if(ip_list != NULL) + free((char *)ip_list); + + } else { + connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); + } + } + + if (!connected_ok) { + DEBUG(0,("domain_client_validate: Domain password server not available.\n")); + cli_shutdown(&cli); + return False; + } + + /* We really don't care what LUID we give the user. */ + generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); + + if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge, + ((smb_apasslen != 0) ? smb_apasswd : NULL), + ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), + &ctr, &info3) == False) { + uint32 nt_rpc_err; + + cli_error(&cli, NULL, NULL, &nt_rpc_err); + DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + + if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL)) + *user_exists = False; + + return False; + } + + /* + * Here, if we really want it, we have lots of info about the user in info3. + */ + +#if 0 + /* + * We don't actually need to do this - plus it fails currently with + * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to + * send here. JRA. + */ + + if(cli_nt_logoff(&cli, &ctr) == False) { + DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ +%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return False; + } +#endif /* 0 */ + + cli_nt_session_close(&cli); + cli_ulogoff(&cli); + cli_shutdown(&cli); + return True; +} -- cgit From 632b4f806eae15e319b8f62caef5d25634cf720c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 3 Jan 2000 06:30:50 +0000 Subject: added suppport for unexpected udp/138 packets I also fixed up the lookup_pdc_name() code so that it now works, even with a NT server that insists on replying to udp/138. The method I used to match packets was to use the mailslot string as a datagram ID. The true dgm_id doesn't work as NT doesn't set it correctly. uggh. PS: Jeremy, I had to change your code quite a bit, are you sure this worked with a Samba PDC?? The code looked broken, it got the offsets wrong in the SMB portion of the packet and filled in the IP incorrectly. (This used to be commit 32f66f4ea63038cb4b3785bdf1762abdde076f5d) --- source3/smbd/password.c | 163 ++++++++++++++++++++++++++---------------------- 1 file changed, 88 insertions(+), 75 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9792c9ebc8..ca588c6681 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -959,16 +959,18 @@ struct cli_state *server_cryptkey(void) struct cli_state *cli; fstring desthost; struct in_addr dest_ip; - char *p; - BOOL connected_ok = False; + char *p, *pserver; + BOOL connected_ok = False; cli = server_client(); if (!cli_initialise(cli)) return NULL; - p = lp_passwordserver(); - while(p && next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { + pserver = strdup(lp_passwordserver()); + p = pserver; + + while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { standard_sub_basic(desthost); strupper(desthost); @@ -989,6 +991,8 @@ struct cli_state *server_cryptkey(void) } } + free(pserver); + if (!connected_ok) { DEBUG(0,("password server not available\n")); cli_shutdown(cli); @@ -1249,15 +1253,79 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un * Ignore addresses we have already tried. */ - if(ip_equal(ipzero, *ip)) - return False; + if (ip_equal(ipzero, *ip)) + return False; - if(!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) - return False; + if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) + return False; return connect_to_domain_password_server(pcli, dc_name, trust_passwd); } + + +/*********************************************************************** + We have been asked to dynamcially determine the IP addresses of + the PDC and BDC's for this DOMAIN, and query them in turn. +************************************************************************/ +static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd) +{ + struct in_addr *ip_list = NULL; + int count = 0; + int i; + BOOL connected_ok = False; + + if (!get_dc_list(lp_workgroup(), &ip_list, &count)) + return False; + + /* + * Firstly try and contact a PDC/BDC who has the same + * network address as any of our interfaces. + */ + for(i = 0; i < count; i++) { + if(!is_local_net(ip_list[i])) + continue; + + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Secondly try and contact a random PDC/BDC. + */ + if(!connected_ok) { + i = (sys_random() % count); + + if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + ip_list[i] = ipzero; /* Tried and failed. */ + } + + /* + * Finally go through the IP list in turn, ignoring any addresses + * we have already tried. + */ + if(!connected_ok) { + /* + * Try and connect to any of the other IP addresses in the PDC/BDC list. + * Note that from a WINS server the #1 IP address is the PDC. + */ + for(i = 0; i < count; i++) { + if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) + break; + } + } + + if(ip_list != NULL) + free((char *)ip_list); + + + return connected_ok; +} + + + /*********************************************************************** Do the same as security=server, but using NT Domain calls and a session key from the machine password. @@ -1273,7 +1341,7 @@ BOOL domain_client_validate( char *user, char *domain, unsigned char local_nt_reponse[24]; unsigned char trust_passwd[16]; fstring remote_machine; - char *p; + char *p, *pserver; NET_ID_INFO_CTR ctr; NET_USER_INFO_3 info3; struct cli_state cli; @@ -1349,75 +1417,20 @@ BOOL domain_client_validate( char *user, char *domain, * PDC/BDC. Contact each in turn and try and authenticate. */ - p = lp_passwordserver(); - while(!connected_ok && p && - next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { - if(strequal(remote_machine, "*")) { - - /* - * We have been asked to dynamcially determine the IP addresses of - * the PDC and BDC's for this DOMAIN, and query them in turn. - */ - - struct in_addr *ip_list = NULL; - int count = 0; - int i; - - if(!get_dc_list(lp_workgroup(), &ip_list, &count)) - continue; - - /* - * Firstly try and contact a PDC/BDC who has the same - * network address as any of our interfaces. - */ - - for(i = 0; i < count; i++) { - if(!is_local_net(ip_list[i])) - continue; - - if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) - break; - - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Secondly try and contact a random PDC/BDC. - */ - - if(!connected_ok) { - i = (sys_random() % count); + pserver = strdup(lp_passwordserver()); + p = pserver; - if(!(connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Finally go through the IP list in turn, ignoring any addresses - * we have already tried. - */ - - if(!connected_ok) { - - /* - * Try and connect to any of the other IP addresses in the PDC/BDC list. - * Note that from a WINS server the #1 IP address is the PDC. - */ - - for(i = 0; i < count; i++) { - if((connected_ok = attempt_connect_to_dc(&cli, &ip_list[i], trust_passwd))) - break; - } - } - - if(ip_list != NULL) - free((char *)ip_list); - - } else { - connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); - } + while (!connected_ok && + next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { + if(strequal(remote_machine, "*")) { + connected_ok = find_connect_pdc(&cli, trust_passwd); + } else { + connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); + } } + free(pserver); + if (!connected_ok) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); cli_shutdown(&cli); -- cgit From 7434c1aabdee5e71ffc752d9df7250808c824d46 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 4 Jan 2000 01:01:27 +0000 Subject: Fixed getgrent() recurse problem. Jeremy. (This used to be commit b5420f6152d5df415231cb3fdf614542dbbd7db3) --- source3/smbd/password.c | 53 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ca588c6681..e7f7f2c039 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -618,24 +618,61 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) #ifdef HAVE_GETGRENT { struct group *gptr; - char **member; setgrent(); while ((gptr = (struct group *)getgrent())) { - if (!strequal(gptr->gr_name,group)) - continue; - member = gptr->gr_mem; - while (member && *member) { + if (strequal(gptr->gr_name,group)) + break; + } + + /* + * As user_ok can recurse doing a getgrent(), we must + * copy the member list into a pstring on the stack before + * use. Bug pointed out by leon@eatworms.swmed.edu. + */ + + if (gptr) { + pstring member_list; + char *member; + size_t copied_len = 0; + int i; + + *member_list = '\0'; + member = member_list; + + for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { + size_t member_len = strlen(gptr->gr_mem[i]) + 1; + if( copied_len + member_len < sizeof(pstring)) { + + DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i])); + + safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1); + copied_len += member_len; + member += copied_len; + } else { + *member = '\0'; + } + } + + endgrent(); + + member = member_list; + while (*member) { static fstring name; - fstrcpy(name,*member); + fstrcpy(name,member); if (user_ok(name,snum) && password_ok(name,password,pwlen,NULL)) { endgrent(); return(&name[0]); } - member++; + + DEBUG(10,("validate_group = member = %s\n", member)); + + member += strlen(member) + 1; } + } else { + endgrent(); + return NULL; } - endgrent(); } #endif return(NULL); -- cgit From 171da4d78736730557a94b44af9f2d62081b80ba Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 7 Jan 2000 06:55:36 +0000 Subject: this looks like a big commit, but it isn't really :) This fixes our netbios scope handling. We now have a 'netbios scope' option in smb.conf and the scope option is removed from make_nmb_name() this was prompted by a bug in our PDC finding code where it didn't append the scope to the query of the '*' name. (This used to be commit b563be824b8c3141c49558eced7829b48d4ab26f) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e7f7f2c039..44fbdfa8ec 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -28,7 +28,6 @@ extern struct in_addr ipzero; /* users from session setup */ static pstring session_users=""; -extern pstring scope; extern pstring global_myname; extern fstring global_myworkgroup; -- cgit From 3cf31a194f5721b67b1255e3f168d4bc87d433fc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 15 Feb 2000 19:36:47 +0000 Subject: Added replacement functions sys_popen and sys_pclose. These are based on the glibc source code and are safer than the traditional popen as they don't use a shell to exec the requested command. Now we have these functions they can be tightened up (environment etc.) as required to make a safe popen. It should now be safe to add the environement variable loading code to loadparm.c Jeremy. (This used to be commit b52e92b09d4ca3b66e534f520468dee27065d048) --- source3/smbd/password.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 44fbdfa8ec..19e7d36443 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -175,14 +175,10 @@ int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_gro ngroups = sys_getgroups(0,&grp); if (ngroups <= 0) { - ngroups = 32; + ngroups = groups_max(); } -#ifdef NGROUPS_MAX - if((groups = (gid_t *)malloc(sizeof(gid_t)*NGROUPS_MAX)) == NULL) -#else /* NGROUPS_MAX */ if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) -#endif /* NGROUPS_MAX */ { DEBUG(0,("setup_groups malloc fail !\n")); return -1; -- cgit From 83ee9372fc18eaef6d00fbc7c1fb68747e2303bb Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 10 Mar 2000 18:10:10 +0000 Subject: you know, when you do a cvs commit, you _really_ expect it to actually work. this explains why j-f wasn't happy. (This used to be commit c51e38214a5323d0aa9b6dcd948a76ddc29f5305) --- source3/smbd/password.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 19e7d36443..bdb0385a48 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -122,18 +122,12 @@ void invalidate_vuid(uint16 vuid) vuser->uid = (uid_t)-1; vuser->gid = (gid_t)-1; - vuser->n_sids = 0; - /* same number of igroups as groups */ vuser->n_groups = 0; if (vuser->groups) free((char *)vuser->groups); - if (vuser->sids) - free((char *)vuser->sids); - - vuser->sids = NULL; vuser->groups = NULL; } @@ -255,9 +249,6 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, fstrcpy(vuser->name,unix_name); fstrcpy(vuser->requested_name,requested_name); - vuser->n_sids = 0; - vuser->sids = NULL; - vuser->n_groups = 0; vuser->groups = NULL; -- cgit From 2fa922611bf7160e2c1ce80c11b50006448bf98d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 11 Apr 2000 13:55:53 +0000 Subject: finally got sick of the "extern int Client" code and the stupid assumption that we have one socket everywhere while doing so I discovered a few bugs! 1) the clientgen session retarget code if used from smbd or nmbd would cause a crash as it called close_sockets() which closed our main socket! fixed by removing close_sockets() completely - it is unnecessary 2) the caching in client_addr() and client_name() was bogus - it could easily get fooled and give the wrong result. fixed. 3) the retarget could could recurse, allowing an easy denial of service attack on nmbd. fixed. (This used to be commit 5937ab14d222696e40a3fc6f0e6a536f2d7305d3) --- source3/smbd/password.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index bdb0385a48..208dbd2bff 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -943,8 +943,7 @@ BOOL check_hosts_equiv(char *user) /* note: don't allow hosts.equiv on root */ if (fname && *fname && (pass->pw_uid != 0)) { - extern int Client; - if (check_user_equiv(user,client_name(Client),fname)) + if (check_user_equiv(user,client_name(),fname)) return(True); } @@ -952,9 +951,8 @@ BOOL check_hosts_equiv(char *user) { char *home = get_user_home_dir(user); if (home) { - extern int Client; slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); - if (check_user_equiv(user,client_name(Client),rhostsfile)) + if (check_user_equiv(user,client_name(),rhostsfile)) return(True); } } -- cgit From 8d7e498db160f9a366400fc1c55dacbcffaf4196 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Apr 2000 11:17:19 +0000 Subject: converted a couple more functions to use a fd instead of a FILE* added a new utility fn file_lines_slashcont() which is used to handle files that treat a \ followed by a newline as a blank (This used to be commit 384ecd9d66ccd31ee85000c0ca55d413d8f2cc53) --- source3/smbd/password.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 208dbd2bff..f92d31718c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -828,15 +828,16 @@ allows this user from this machine ****************************************************************************/ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { - pstring buf; int plus_allowed = 1; char *file_host; char *file_user; - FILE *fp = sys_fopen(equiv_file, "r"); + char **lines = file_lines_load(equiv_file, NULL); + int i; + DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); - if (! fp) return False; - while(fgets(buf, sizeof(buf), fp)) - { + if (! lines) return False; + for (i=0; lines[i]; i++) { + char *buf = lines[i]; trim_string(buf," "," "); if (buf[0] != '#' && buf[0] != '\n') @@ -857,7 +858,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { /* a bare plus means everbody allowed */ DEBUG(6, ("check_user_equiv everybody allowed\n")); - fclose(fp); + file_lines_free(lines); return True; } } @@ -912,17 +913,17 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) /* is it this user */ if (file_user == 0 || strequal(user, file_user)) { - fclose(fp); DEBUG(5, ("check_user_equiv matched %s%s %s\n", (plus ? "+" : "-"), file_host, (file_user ? file_user : ""))); + file_lines_free(lines); return (plus ? True : False); } } } } } - fclose(fp); + file_lines_free(lines); return False; } -- cgit From 693ffb8466ada58ecc59fde754ba79fc6f51528d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 2 May 2000 02:23:41 +0000 Subject: Added sys_fork() and sys_getpid() functions to stop the overhead of doing a system call every time we want to just get our pid. Jeremy. (This used to be commit 148628b616b5c29ba6340d65fc3ddbcabba6e67a) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f92d31718c..a8b9050030 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -53,8 +53,8 @@ void generate_next_challenge(char *challenge) /* get a sort-of random number */ GetTimeOfDay(&tval); - v1 = (counter++) + getpid() + tval.tv_sec; - v2 = (counter++) * getpid() + tval.tv_usec; + v1 = (counter++) + sys_getpid() + tval.tv_sec; + v2 = (counter++) * sys_getpid() + tval.tv_usec; SIVAL(challenge,0,v1); SIVAL(challenge,4,v2); -- cgit From 32d5416b6a777a7874fec8518ec44e750560d882 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 2 May 2000 13:55:42 +0000 Subject: split the username in the vuser structure into a separate userdom_struct. As the name implies this also contains a domain (unused at the moment). This will be important shortly, as operation in appliance mode needs the domain to be always carried with the username. (This used to be commit ee8546342d5be90e730372b985710d764564b124) --- source3/smbd/password.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a8b9050030..cff47c0a94 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -140,7 +140,7 @@ char *validated_username(uint16 vuid) user_struct *vuser = get_valid_user_struct(vuid); if (vuser == NULL) return 0; - return(vuser->name); + return(vuser->user.unix_name); } @@ -246,8 +246,8 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, vuser->uid = uid; vuser->gid = gid; vuser->guest = guest; - fstrcpy(vuser->name,unix_name); - fstrcpy(vuser->requested_name,requested_name); + fstrcpy(vuser->user.unix_name,unix_name); + fstrcpy(vuser->user.smb_name,requested_name); vuser->n_groups = 0; vuser->groups = NULL; @@ -261,12 +261,12 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); - fstrcpy(vuser->real_name, "\0"); + fstrcpy(vuser->user.real_name, ""); if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->name))!= NULL) + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->name,pwfile->pw_gecos)); - fstrcpy(vuser->real_name, pwfile->pw_gecos); + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); + fstrcpy(vuser->user.real_name, pwfile->pw_gecos); } } @@ -707,9 +707,9 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { - if (user_ok(vuser->name,snum) && - password_ok(vuser->name, password, pwlen, NULL)) { - fstrcpy(user, vuser->name); + if (user_ok(vuser->user.unix_name,snum) && + password_ok(vuser->user.unix_name, password, pwlen, NULL)) { + fstrcpy(user, vuser->user.unix_name); vuser->guest = False; DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); ok = True; @@ -744,8 +744,8 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check for a previously validated username/password pair */ if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) && (vuser != 0) && !vuser->guest && - user_ok(vuser->name,snum)) { - fstrcpy(user,vuser->name); + user_ok(vuser->user.unix_name,snum)) { + fstrcpy(user,vuser->user.unix_name); *guest = False; DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); ok = True; -- cgit From 99352a098656ac9d3886d047ff273a6880990d2f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 3 May 2000 02:24:01 +0000 Subject: Insure uninitialized memory read fixes. Jeremy. (This used to be commit 577ddbfbec857dec3ade811f735ec6b183566435) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index cff47c0a94..989d3f045d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -270,6 +270,8 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, } } + memset(&vuser->dc, '\0', sizeof(vuser->dc)); + return (uint16)((num_validated_users - 1) + VUID_OFFSET); } -- cgit From f3a861e04e33901c89408a9c89ebaa81fc606f97 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 May 2000 07:59:34 +0000 Subject: - use full_name instead of real_name - got rid of guest map code in lpq parser (This used to be commit 8e53f781d3cf6a7007764916a0d8e8f1abea1f66) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 989d3f045d..a727d2feb3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -261,12 +261,12 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); - fstrcpy(vuser->user.real_name, ""); + fstrcpy(vuser->user.full_name, ""); if (lp_unix_realname()) { if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); - fstrcpy(vuser->user.real_name, pwfile->pw_gecos); + fstrcpy(vuser->user.full_name, pwfile->pw_gecos); } } -- cgit From f6844e0b7eb4412bc44c5533b09f856dc9272e75 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 4 May 2000 16:01:47 +0000 Subject: a minimal change to get appliance mode to work with winbindd we needed to accept usernames of the form DOMAIN/user, which means we needed to pass the domain to a getpwnam() like routine in certain critical spots. What I'd rather do is get rid of "char *user" everywhere and use the new userdom_struct, but that will have to wait a few days. (This used to be commit 8b7a10febead8be182e7d5b1d68259e31530b69c) --- source3/smbd/password.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a727d2feb3..782d04631a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -137,23 +137,35 @@ return a validated username ****************************************************************************/ char *validated_username(uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) - return 0; - return(vuser->user.unix_name); + user_struct *vuser = get_valid_user_struct(vuid); + if (vuser == NULL) + return 0; + return(vuser->user.unix_name); +} + +/**************************************************************************** +return a validated domain +****************************************************************************/ +char *validated_domain(uint16 vuid) +{ + user_struct *vuser = get_valid_user_struct(vuid); + if (vuser == NULL) + return 0; + return(vuser->user.domain); } /**************************************************************************** Setup the groups a user belongs to. ****************************************************************************/ -int setup_groups(char *user, uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) +int setup_groups(char *user, char *domain, + uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) { int i,ngroups; gid_t grp = 0; gid_t *groups = NULL; - if (-1 == initgroups(user,gid)) + if (-1 == smb_initgroups(user,domain,gid)) { DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); if (getuid() == 0) @@ -199,7 +211,8 @@ register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, BOOL guest) +uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, + char *domain,BOOL guest) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -248,13 +261,14 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, vuser->guest = guest; fstrcpy(vuser->user.unix_name,unix_name); fstrcpy(vuser->user.smb_name,requested_name); + fstrcpy(vuser->user.domain,domain); vuser->n_groups = 0; vuser->groups = NULL; /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(unix_name,uid,gid, + setup_groups(unix_name,domain,uid,gid, &vuser->n_groups, &vuser->groups); -- cgit From 2958dfcdf87d5169fe1152806be6ad03acb04d88 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 8 May 2000 10:42:21 +0000 Subject: added secrets.tdb and changed storage of trust account password to use it (This used to be commit 88ad00b82acc4636ab57dfe710af08ea85b82ff1) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 782d04631a..0478e205d1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1435,7 +1435,7 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password. */ - if (!trust_get_passwd( trust_passwd, global_myworkgroup, global_myname)) + if (!get_trust_account_password(domain, trust_passwd, NULL)) { return False; } -- cgit From 4c061ca15cd1e9b0e2ce32218727c4040757c98d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 9 May 2000 15:09:52 +0000 Subject: - use smb_gwtpwnam() in another couple of places - don't call add/del user if the scripts are empty (This used to be commit 43860215d4d16cb1bacdc77f1c46c54e4c54abd7) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0478e205d1..70663f0909 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -491,7 +491,7 @@ BOOL pass_check_smb(char *user, char *domain, } else { - pass = Get_Pwnam(user,True); + pass = smb_getpwnam(user,domain,True); } if (pass == NULL) -- cgit From 49a0e6d5989656c1b3c9c063a20308ca4ee5d73b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 10:41:59 +0000 Subject: more merging voodoo this adds "#define OLD_NTDOMAIN 1" in lots of places. Don't panic - this isn't permanent, it should go after another few merge steps have been done (This used to be commit 92109d7b3c06f240452d39f669ecb8c9c86ab610) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 70663f0909..325600e92e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1,3 +1,5 @@ +#define OLD_NTDOMAIN 1 + /* Unix SMB/Netbios implementation. Version 1.9. @@ -1523,3 +1525,5 @@ BOOL domain_client_validate( char *user, char *domain, cli_shutdown(&cli); return True; } + +#undef OLD_NTDOMAIN -- cgit From a71d9b291c5365f08250b77d281f4cc8f24ec2e2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 13:21:32 +0000 Subject: treat a blank "password server =" line as a "*" if in domain security (This used to be commit 5a617c013cce65434d315dc33279a4bc28dc63de) --- source3/smbd/password.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 325600e92e..3953c5b0e3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1457,7 +1457,8 @@ BOOL domain_client_validate( char *user, char *domain, * PDC/BDC. Contact each in turn and try and authenticate. */ - pserver = strdup(lp_passwordserver()); + pserver = lp_passwordserver(); + if (! *pserver) pserver = "*"; p = pserver; while (!connected_ok && @@ -1469,8 +1470,6 @@ BOOL domain_client_validate( char *user, char *domain, } } - free(pserver); - if (!connected_ok) { DEBUG(0,("domain_client_validate: Domain password server not available.\n")); cli_shutdown(&cli); -- cgit From 43a3faab0831a866559ca56e70c81be582047d0b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 10 May 2000 14:48:33 +0000 Subject: - changed smb_getpwnam() to use winbind style usernames - finished ntdom -> winbind rename in head (This used to be commit ada483cb56453afc6df4ec4be18bfe5e943c7150) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3953c5b0e3..314b3dd3c7 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -493,7 +493,7 @@ BOOL pass_check_smb(char *user, char *domain, } else { - pass = smb_getpwnam(user,domain,True); + pass = smb_getpwnam(user,True); } if (pass == NULL) -- cgit From ebd73f37a2103965eea4967b3983b8a6219316a1 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 May 2000 05:07:26 +0000 Subject: use our primary domain trust account for trusted domain authentication (This used to be commit db90a4b9609a980fa2f4328d38a0d2c60a1384a0) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 314b3dd3c7..f9aa10eced 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1435,9 +1435,9 @@ BOOL domain_client_validate( char *user, char *domain, } /* - * Get the machine account password. + * Get the machine account password for our primary domain */ - if (!get_trust_account_password(domain, trust_passwd, NULL)) + if (!get_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { return False; } -- cgit From 479c73559e137a406f912f8e262e1658861dc9db Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 May 2000 06:30:45 +0000 Subject: use "winbind separator" option for domain/user separator character (This used to be commit 6cbb826b154e61085fd651116caf472d4d438c1d) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f9aa10eced..95f03ab204 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -167,7 +167,7 @@ int setup_groups(char *user, char *domain, gid_t grp = 0; gid_t *groups = NULL; - if (-1 == smb_initgroups(user,domain,gid)) + if (-1 == initgroups(user,gid)) { DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); if (getuid() == 0) -- cgit From 7f2b42abec143e06971114c9292ac9539d012456 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 24 May 2000 06:36:10 +0000 Subject: got rid of lp_revalidate() (This used to be commit 8dea95e62c7f4723cd4b71c1b03c613386392c49) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 95f03ab204..614e5a84fc 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -760,7 +760,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, } /* check for a previously validated username/password pair */ - if (!ok && (!lp_revalidate(snum) || lp_security() > SEC_SHARE) && + if (!ok && (lp_security() > SEC_SHARE) && (vuser != 0) && !vuser->guest && user_ok(vuser->user.unix_name,snum)) { fstrcpy(user,vuser->user.unix_name); -- cgit From da44845a0907bc6c9da9aabc0374b8280a85017f Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 3 Jun 2000 06:22:19 +0000 Subject: moved secrets fns into secrets.c (This used to be commit f890bcf06786e7c63bf76fad2fd46d287a99a270) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 614e5a84fc..d3a728bf42 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1437,7 +1437,7 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password for our primary domain */ - if (!get_trust_account_password(lp_workgroup(), trust_passwd, NULL)) + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { return False; } -- cgit From 84d40095e1d7ba5c66cabfd2d41012162d652970 Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Thu, 8 Jun 2000 13:56:07 +0000 Subject: added a NET_USER_INFO_3 struct to user_struct. register_vuid fills it with constructed info. (This used to be commit b1889e4334012b1b2caa604b859da4271509fc87) --- source3/smbd/password.c | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index d3a728bf42..5815bbd164 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -214,7 +214,8 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest) + char *domain,BOOL guest, + NET_USER_INFO_3 *usr) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -274,6 +275,38 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, &vuser->n_groups, &vuser->groups); + if (usr == NULL) + { + int i; + extern DOM_SID global_sam_sid; + + DEBUG(0,("vuser struct usr being filled in with trash, today\n")); + DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); + DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); + DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); + DEBUG(0,("as soon as possible.\n")); + vuser->usr.user_id = pdb_uid_to_user_rid(uid); + vuser->usr.group_id = pdb_gid_to_group_rid(gid); + vuser->usr.num_groups = vuser->n_groups; + for (i = 0; i < vuser->usr.num_groups; i++) + { + DOM_GID *ntgid = &vuser->usr.gids[i]; + ntgid->attr = 0x7; + ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); + } + + /* this is possibly the worst thing to do, ever. it assumes */ + /* that all users of this system are in the local SAM database */ + /* however, because there is no code to do anything otherwise, */ + /* we have no choice */ + + init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); + } + else + { + vuser->usr = *usr; + } + DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); -- cgit From 28555ec92e061aafb31a9b071caf00e44132c70f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 Jun 2000 17:50:19 +0000 Subject: include/smb.h: Removed NET_USER_3 struct from user struct. It doesn't belong there (yet) as there is no infrastructure for it. Replaced it with a dynamic array of group SIDs plus a user. passdb/passdb.c: Added setup_user_sids() function. This is where the lookup should be done, eventually calling winbind. smbd/password.c: Changed to call setup_user_sids(). Removed spurious DEBUG(0) statements. smbd/reply.c: Removed extra parameter to register_vuid(). Jeremy. (This used to be commit 425f4ad9a5e0e7d49620276100ade7a0cae47011) --- source3/smbd/password.c | 81 +++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 53 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 5815bbd164..b8f5c5cf84 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -117,20 +117,27 @@ invalidate a uid ****************************************************************************/ void invalidate_vuid(uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); + user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) return; + if (vuser == NULL) + return; - vuser->uid = (uid_t)-1; - vuser->gid = (gid_t)-1; + vuser->uid = (uid_t)-1; + vuser->gid = (gid_t)-1; - /* same number of igroups as groups */ - vuser->n_groups = 0; + ZERO_STRUCT(vuser->user_sid); - if (vuser->groups) - free((char *)vuser->groups); + /* same number of igroups as groups */ + vuser->n_groups = 0; - vuser->groups = NULL; + if (vuser->groups) + free((char *)vuser->groups); + + if (vuser->group_sids) + free((char *)vuser->group_sids); + + vuser->groups = NULL; + vuser->group_sids = NULL; } @@ -207,15 +214,14 @@ int setup_groups(char *user, char *domain, return 0; } - /**************************************************************************** -register a uid/name pair as being valid and that a valid password -has been given. vuid is biased by an offset. This allows us to -tell random client vuid's (normally zero) from valid vuids. + Register a uid/name pair as being valid and that a valid password + has been given. vuid is biased by an offset. This allows us to + tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ + uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest, - NET_USER_INFO_3 *usr) + char *domain,BOOL guest) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -249,12 +255,11 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, sizeof(user_struct)* (num_validated_users+1)); - if (!validated_users) - { + if (!validated_users) { DEBUG(0,("Failed to realloc users struct!\n")); num_validated_users = 0; return UID_FIELD_INVALID; - } + } vuser = &validated_users[num_validated_users]; num_validated_users++; @@ -275,50 +280,20 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, &vuser->n_groups, &vuser->groups); - if (usr == NULL) - { - int i; - extern DOM_SID global_sam_sid; - - DEBUG(0,("vuser struct usr being filled in with trash, today\n")); - DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); - DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); - DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); - DEBUG(0,("as soon as possible.\n")); - vuser->usr.user_id = pdb_uid_to_user_rid(uid); - vuser->usr.group_id = pdb_gid_to_group_rid(gid); - vuser->usr.num_groups = vuser->n_groups; - for (i = 0; i < vuser->usr.num_groups; i++) - { - DOM_GID *ntgid = &vuser->usr.gids[i]; - ntgid->attr = 0x7; - ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); - } - - /* this is possibly the worst thing to do, ever. it assumes */ - /* that all users of this system are in the local SAM database */ - /* however, because there is no code to do anything otherwise, */ - /* we have no choice */ - - init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); - } - else - { - vuser->usr = *usr; - } - DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->user.full_name, ""); if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) - { + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } + } } + /* Map this uid into user and group SIDs. */ + setup_user_sids(vuser); + memset(&vuser->dc, '\0', sizeof(vuser->dc)); return (uint16)((num_validated_users - 1) + VUID_OFFSET); -- cgit From c3487b00dd1dde7fa0511211f466acc1c05d8f3d Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Jun 2000 01:26:42 +0000 Subject: reverted jeremy's changes that removed NET_USER_INFO_3. will you please not just undercut work in progress, thank you. (This used to be commit 86d440a88c948727bfcfedc694c52c58f9687d8b) --- source3/smbd/password.c | 81 ++++++++++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 28 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b8f5c5cf84..5815bbd164 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -117,27 +117,20 @@ invalidate a uid ****************************************************************************/ void invalidate_vuid(uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); - - if (vuser == NULL) - return; - - vuser->uid = (uid_t)-1; - vuser->gid = (gid_t)-1; + user_struct *vuser = get_valid_user_struct(vuid); - ZERO_STRUCT(vuser->user_sid); + if (vuser == NULL) return; - /* same number of igroups as groups */ - vuser->n_groups = 0; + vuser->uid = (uid_t)-1; + vuser->gid = (gid_t)-1; - if (vuser->groups) - free((char *)vuser->groups); + /* same number of igroups as groups */ + vuser->n_groups = 0; - if (vuser->group_sids) - free((char *)vuser->group_sids); + if (vuser->groups) + free((char *)vuser->groups); - vuser->groups = NULL; - vuser->group_sids = NULL; + vuser->groups = NULL; } @@ -214,14 +207,15 @@ int setup_groups(char *user, char *domain, return 0; } + /**************************************************************************** - Register a uid/name pair as being valid and that a valid password - has been given. vuid is biased by an offset. This allows us to - tell random client vuid's (normally zero) from valid vuids. +register a uid/name pair as being valid and that a valid password +has been given. vuid is biased by an offset. This allows us to +tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ - uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest) + char *domain,BOOL guest, + NET_USER_INFO_3 *usr) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -255,11 +249,12 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, sizeof(user_struct)* (num_validated_users+1)); - if (!validated_users) { + if (!validated_users) + { DEBUG(0,("Failed to realloc users struct!\n")); num_validated_users = 0; return UID_FIELD_INVALID; - } + } vuser = &validated_users[num_validated_users]; num_validated_users++; @@ -280,20 +275,50 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, &vuser->n_groups, &vuser->groups); + if (usr == NULL) + { + int i; + extern DOM_SID global_sam_sid; + + DEBUG(0,("vuser struct usr being filled in with trash, today\n")); + DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); + DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); + DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); + DEBUG(0,("as soon as possible.\n")); + vuser->usr.user_id = pdb_uid_to_user_rid(uid); + vuser->usr.group_id = pdb_gid_to_group_rid(gid); + vuser->usr.num_groups = vuser->n_groups; + for (i = 0; i < vuser->usr.num_groups; i++) + { + DOM_GID *ntgid = &vuser->usr.gids[i]; + ntgid->attr = 0x7; + ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); + } + + /* this is possibly the worst thing to do, ever. it assumes */ + /* that all users of this system are in the local SAM database */ + /* however, because there is no code to do anything otherwise, */ + /* we have no choice */ + + init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); + } + else + { + vuser->usr = *usr; + } + DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->user.full_name, ""); if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) + { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } + } } - /* Map this uid into user and group SIDs. */ - setup_user_sids(vuser); - memset(&vuser->dc, '\0', sizeof(vuser->dc)); return (uint16)((num_validated_users - 1) + VUID_OFFSET); -- cgit From ad98207f54a7e3d88108d34c4cf365d5f8bc23ef Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Jun 2000 03:00:34 +0000 Subject: dynamic allocation of NET_USER_INFO_3 gids. jeremy, the intent is to call se_access_check() with usr-sid, grp-sid, array-of-group-rids (but array-of-group-sids would do). please do look at smbd/lanman.c's api_NetWkstaGetInfo, it will show you that we really do need to store the entire NET_USER_INFO_3 structure. then again, api_NetWkstaGetInfo is only used by win9x so who cares :) (This used to be commit bd34f652390adc32c4959d164c628687f526d977) --- source3/smbd/password.c | 60 ++++++++++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 5815bbd164..6201b85357 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -277,30 +277,37 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, if (usr == NULL) { - int i; - extern DOM_SID global_sam_sid; - - DEBUG(0,("vuser struct usr being filled in with trash, today\n")); - DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); - DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); - DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); - DEBUG(0,("as soon as possible.\n")); - vuser->usr.user_id = pdb_uid_to_user_rid(uid); - vuser->usr.group_id = pdb_gid_to_group_rid(gid); - vuser->usr.num_groups = vuser->n_groups; - for (i = 0; i < vuser->usr.num_groups; i++) - { - DOM_GID *ntgid = &vuser->usr.gids[i]; - ntgid->attr = 0x7; - ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); - } - - /* this is possibly the worst thing to do, ever. it assumes */ - /* that all users of this system are in the local SAM database */ - /* however, because there is no code to do anything otherwise, */ - /* we have no choice */ + int i; + extern DOM_SID global_sam_sid; + + DEBUG(0,("vuser struct usr being filled in with trash, today\n")); + DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); + DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); + DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); + DEBUG(0,("as soon as possible.\n")); + vuser->usr.user_id = pdb_uid_to_user_rid(uid); + vuser->usr.group_id = pdb_gid_to_group_rid(gid); + vuser->usr.num_groups = vuser->n_groups; + if (vuser->n_groups != 0) + { + vuser->usr.gids = g_new(DOM_GID, vuser->usr.num_groups); + if (vuser->usr.gids == NULL) + return UID_FIELD_INVALID; + } - init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); + for (i = 0; i < vuser->usr.num_groups; i++) + { + DOM_GID *ntgid = &vuser->usr.gids[i]; + ntgid->attr = 0x7; + ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); + } + + /* this is possibly the worst thing to do, ever. it assumes */ + /* that all users of this system are in the local SAM database */ + /* however, because there is no code to do anything otherwise, */ + /* we have no choice */ + + init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); } else { @@ -1525,12 +1532,19 @@ BOOL domain_client_validate( char *user, char *domain, cli_ulogoff(&cli); cli_shutdown(&cli); + /* unused, so delete here. */ + if (info3.gids != NULL) + free (info3.gids); + if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL)) *user_exists = False; return False; } + /* unused, so delete here. */ + if (info3.gids != NULL) + free (info3.gids); /* * Here, if we really want it, we have lots of info about the user in info3. */ -- cgit From 979f509e74c7cb2071478b9b1da9f254d98920cb Mon Sep 17 00:00:00 2001 From: Luke Leighton Date: Fri, 9 Jun 2000 03:30:54 +0000 Subject: free NET_USER_INFO_3 gids when vuser invalidated. (This used to be commit 2f056c2aadd2e16d89b66aabd1c166ab8d5abd76) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6201b85357..4110530c0b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -131,6 +131,10 @@ void invalidate_vuid(uint16 vuid) free((char *)vuser->groups); vuser->groups = NULL; + + if (vuser->usr.gids != NULL) + free (vuser->usr.gids); + vuser->usr.gids = NULL; } -- cgit From 03e0164270ffd7ceeb8df6f3cc3917c111dc05f8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 9 Jun 2000 18:45:31 +0000 Subject: Luke, I am moving the code back into passdb/passdb.c, this the correct place to do this, not in smbd/passwd.c Please don't change this without asking first, I have run this past Andrew so talk to him (I'm on vacation next week). I also removed the g_newXXX macros. There are essentially a private C extension, not used anywhere else in the code, and add no functionality over malloc(XX) and make the code harder to understand (everyone knows what malloc does). Jeremy. (This used to be commit e1b1b6fb6794ba02e1fea510a981fa0ce0d12b58) --- source3/smbd/password.c | 66 +++++++++++-------------------------------------- 1 file changed, 14 insertions(+), 52 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4110530c0b..c38a6a0f2b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -117,24 +117,24 @@ invalidate a uid ****************************************************************************/ void invalidate_vuid(uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); + user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) return; + if (vuser == NULL) + return; - vuser->uid = (uid_t)-1; - vuser->gid = (gid_t)-1; + vuser->uid = (uid_t)-1; + vuser->gid = (gid_t)-1; - /* same number of igroups as groups */ - vuser->n_groups = 0; + /* same number of igroups as groups */ + vuser->n_groups = 0; - if (vuser->groups) - free((char *)vuser->groups); + if (vuser->groups) + free((char *)vuser->groups); - vuser->groups = NULL; + vuser->groups = NULL; - if (vuser->usr.gids != NULL) - free (vuser->usr.gids); - vuser->usr.gids = NULL; + if (vuser->group_sids != NULL) + free (vuser->group_sids); } @@ -218,8 +218,7 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest, - NET_USER_INFO_3 *usr) + char *domain,BOOL guest) { user_struct *vuser; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -279,44 +278,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, &vuser->n_groups, &vuser->groups); - if (usr == NULL) - { - int i; - extern DOM_SID global_sam_sid; - - DEBUG(0,("vuser struct usr being filled in with trash, today\n")); - DEBUG(0,("this needs to be replaced with a proper surs impl.\n")); - DEBUG(0,("e.g. the one used in winbindd. in fact, all\n")); - DEBUG(0,("occurrences of pdb_xxx_to_xxx should be replaced\n")); - DEBUG(0,("as soon as possible.\n")); - vuser->usr.user_id = pdb_uid_to_user_rid(uid); - vuser->usr.group_id = pdb_gid_to_group_rid(gid); - vuser->usr.num_groups = vuser->n_groups; - if (vuser->n_groups != 0) - { - vuser->usr.gids = g_new(DOM_GID, vuser->usr.num_groups); - if (vuser->usr.gids == NULL) - return UID_FIELD_INVALID; - } - - for (i = 0; i < vuser->usr.num_groups; i++) - { - DOM_GID *ntgid = &vuser->usr.gids[i]; - ntgid->attr = 0x7; - ntgid->g_rid = pdb_gid_to_group_rid(vuser->groups[i]); - } - - /* this is possibly the worst thing to do, ever. it assumes */ - /* that all users of this system are in the local SAM database */ - /* however, because there is no code to do anything otherwise, */ - /* we have no choice */ - - init_dom_sid2(&vuser->usr.dom_sid, &global_sam_sid); - } - else - { - vuser->usr = *usr; - } + setup_user_sids(vuser); DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); -- cgit From 31e83abd3d275014c2841e66f5d46ef0997e5737 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 14 Jun 2000 01:48:08 +0000 Subject: ZERO_STRUCT() of info3 structure before using it. (This used to be commit efe7f818c927a925f2dee1ef4f6040c137e0c84e) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c38a6a0f2b..06f4d72a40 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1485,6 +1485,8 @@ BOOL domain_client_validate( char *user, char *domain, /* We really don't care what LUID we give the user. */ generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); + ZERO_STRUCT(info3); + if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge, ((smb_apasslen != 0) ? smb_apasswd : NULL), ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), -- cgit From 2a1dbb0acdc3acd837681e148729899fb0160836 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 23 Jun 2000 05:57:48 +0000 Subject: Delete OriginalDir stuff. (This used to be commit 3d0f1845c8cefccfabcfd35694264c1e5f52c3af) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 06f4d72a40..209e4402df 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -329,10 +329,10 @@ static BOOL update_smbpassword_file(char *user, char *password) struct smb_passwd *smbpw; BOOL ret; - become_root(0); + become_root(); smbpw = getsmbpwnam(user); - unbecome_root(0); - + unbecome_root(); + if(smbpw == NULL) { DEBUG(0,("getsmbpwnam returned NULL\n")); return False; -- cgit From 5af35320a92e39b924b0bfebd2c4caae24724231 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 10 Jul 2000 04:57:09 +0000 Subject: Spelling fixes. (This used to be commit c1d242f1dd5b6addbe5d2df22e4759f6682fd9ef) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 209e4402df..fffddb4610 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1384,7 +1384,7 @@ BOOL domain_client_validate( char *user, char *domain, { unsigned char local_challenge[8]; unsigned char local_lm_response[24]; - unsigned char local_nt_reponse[24]; + unsigned char local_nt_response[24]; unsigned char trust_passwd[16]; fstring remote_machine; char *p, *pserver; @@ -1422,11 +1422,11 @@ BOOL domain_client_validate( char *user, char *domain, DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); generate_random_buffer( local_challenge, 8, False); SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); - SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_reponse); + SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_response); smb_apasslen = 24; smb_ntpasslen = 24; smb_apasswd = (char *)local_lm_response; - smb_ntpasswd = (char *)local_nt_reponse; + smb_ntpasswd = (char *)local_nt_response; } else { /* -- cgit From 7f36df301e28dc8ca0e5bfadc109d6e907d9ba2b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 1 Aug 2000 18:32:34 +0000 Subject: Tidyup removing many of the 0xC0000000 | NT_STATUS_XXX stuff (only need NT_STATUS_XXX). Removed IS_BITS_xxx macros as they were just reproducing "C" syntax in a more obscure way. Jeremy. (This used to be commit c55bcec817f47d6162466b193d533c877194124a) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fffddb4610..f9291b8705 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -520,7 +520,7 @@ BOOL pass_check_smb(char *user, char *domain, if(smb_pass->acct_ctrl & ACB_DISABLED) { DEBUG(1,("Account for user '%s' was disabled.\n", user)); return(False); - } + } /* Ensure the uid's match */ if (smb_pass->smb_userid != pass->pw_uid) @@ -529,7 +529,7 @@ BOOL pass_check_smb(char *user, char *domain, return(False); } - if (lm_pwd[0] == '\0' && IS_BITS_SET_ALL(smb_pass->acct_ctrl, ACB_PWNOTREQ) && lp_null_passwords()) + if (lm_pwd[0] == '\0' && (smb_pass->acct_ctrl & ACB_PWNOTREQ) && lp_null_passwords()) { DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name)); return(True); -- cgit From 17dcd9a834fc915fb1ff2d8042a23000eeb7acfa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 2 Aug 2000 02:11:55 +0000 Subject: Started to canonicalize our handling of uid -> sid code in order to get ready and fix se_access_check(). Added cannonical lookup_name(), lookup_sid(), uid_to_sid(), gid_to_sid() functions that look via winbind first the fall back on local lookup. All Samba should use these rather than trying to call winbindd code directly. Added NT_USER_TOKEN struct in user_struct, contains list of NT sids associated with this user. se_access_check() should use this (cached) value rather than attempting to do the same thing itself when given a uid/gid pair. More work needs to be done to preserve these things accross security context changes (especially with the tricky pipe problem) but I'm beginning to see how this will be done..... probably by registering a new vuid for an authenticated RPC pipe and not treating the pipe calls specially. More thoughts needed - but we're almost there... Jeremy. (This used to be commit 5e5cc6efe2e4687be59085f562caea1e2e05d0a8) --- source3/smbd/password.c | 113 ++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 67 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f9291b8705..0372e7a0f9 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -112,6 +112,16 @@ user_struct *get_valid_user_struct(uint16 vuid) return &validated_users[vuid]; } +/**************************************************************************** + Delete the SID list for this user. +****************************************************************************/ + +static void delete_nt_token(NT_USER_TOKEN *token) +{ + safe_free( token->user_sids ); + ZERO_STRUCTP(token); +} + /**************************************************************************** invalidate a uid ****************************************************************************/ @@ -133,8 +143,7 @@ void invalidate_vuid(uint16 vuid) vuser->groups = NULL; - if (vuser->group_sids != NULL) - free (vuser->group_sids); + delete_nt_token(&vuser->nt_user_token); } @@ -162,61 +171,54 @@ char *validated_domain(uint16 vuid) /**************************************************************************** -Setup the groups a user belongs to. + Initialize the groups a user belongs to. ****************************************************************************/ -int setup_groups(char *user, char *domain, - uid_t uid, gid_t gid, int *p_ngroups, gid_t **p_groups) -{ - int i,ngroups; - gid_t grp = 0; - gid_t *groups = NULL; - if (-1 == initgroups(user,gid)) - { +int initialize_groups(char *user, uid_t uid, gid_t gid) +{ + if (initgroups(user,gid) == -1) { DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); - if (getuid() == 0) - { - if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) - { + if (getuid() == 0) { + if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) { DEBUG(0,("This is probably a problem with the account %s\n", user)); } } return -1; } + return 0; +} - ngroups = sys_getgroups(0,&grp); - if (ngroups <= 0) - { - ngroups = groups_max(); - } +/**************************************************************************** + Create the SID list for this user. +****************************************************************************/ - if((groups = (gid_t *)malloc(sizeof(gid_t)*ngroups)) == NULL) - { - DEBUG(0,("setup_groups malloc fail !\n")); - return -1; - } +void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups) +{ + DOM_SID *psids; + int i; - ngroups = sys_getgroups(ngroups,groups); + ZERO_STRUCTP(token); - (*p_ngroups) = ngroups; - (*p_groups) = groups; + if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) + return; - DEBUG( 3, ( "%s is in %d groups: ", user, ngroups ) ); - for (i = 0; i < ngroups; i++ ) - { - DEBUG( 3, ( "%s%d", (i ? ", " : ""), (int)groups[i] ) ); - } - DEBUG( 3, ( "\n" ) ); + psids = token->user_sids; - return 0; -} + token->num_sids = ngroups + 2; + + uid_to_sid( &psids[0], uid); + gid_to_sid( &psids[1], gid); + for (i = 0; i < ngroups; i++) + gid_to_sid( &psids[i+2], groups[i]); +} /**************************************************************************** register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ + uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, char *domain,BOOL guest) { @@ -227,37 +229,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, if(lp_security() == SEC_SHARE) return UID_FIELD_INVALID; -#if 0 - /* - * After observing MS-Exchange services writing to a Samba share - * I belive this code is incorrect. Each service does its own - * sessionsetup_and_X for the same user, and as each service shuts - * down, it does a user_logoff_and_X. As we are consolidating multiple - * sessionsetup_and_X's onto the same vuid here, when the first service - * shuts down, it invalidates all the open files for the other services. - * Hence I am removing this code and forcing each sessionsetup_and_X - * to get a new vuid. - * Jeremy Allison. (jallison@whistle.com). - */ - - int i; - for(i = 0; i < num_validated_users; i++) { - vuser = &validated_users[i]; - if ( vuser->uid == uid ) - return (uint16)(i + VUID_OFFSET); /* User already validated */ - } -#endif - validated_users = (user_struct *)Realloc(validated_users, sizeof(user_struct)* (num_validated_users+1)); - if (!validated_users) - { + if (!validated_users) { DEBUG(0,("Failed to realloc users struct!\n")); num_validated_users = 0; return UID_FIELD_INVALID; - } + } vuser = &validated_users[num_validated_users]; num_validated_users++; @@ -274,22 +254,21 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Find all the groups this uid is in and store them. Used by become_user() */ - setup_groups(unix_name,domain,uid,gid, - &vuser->n_groups, - &vuser->groups); + initialize_groups(unix_name, uid, gid); + get_current_groups( &vuser->n_groups, &vuser->groups); - setup_user_sids(vuser); + /* Create an NT_USER_TOKEN struct for this user. */ + setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups); DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); fstrcpy(vuser->user.full_name, ""); if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) - { + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } + } } memset(&vuser->dc, '\0', sizeof(vuser->dc)); -- cgit From f87399915b009f88c41cb75a583c2972fe3daf30 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 3 Aug 2000 22:38:43 +0000 Subject: Added an NT_USER_TOKEN structure that is copied/passed around associated with the current user. This will allow se_access_check() to quickly do a SD check without having to translate uid/gid's to SIDs. Still needs work on pipe calls. Jeremy. (This used to be commit e28d01b744b3dbd33e0e54af4e7f426fa8c082b8) --- source3/smbd/password.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0372e7a0f9..9af7d3b1e9 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -112,16 +112,6 @@ user_struct *get_valid_user_struct(uint16 vuid) return &validated_users[vuid]; } -/**************************************************************************** - Delete the SID list for this user. -****************************************************************************/ - -static void delete_nt_token(NT_USER_TOKEN *token) -{ - safe_free( token->user_sids ); - ZERO_STRUCTP(token); -} - /**************************************************************************** invalidate a uid ****************************************************************************/ @@ -146,7 +136,6 @@ void invalidate_vuid(uint16 vuid) delete_nt_token(&vuser->nt_user_token); } - /**************************************************************************** return a validated username ****************************************************************************/ @@ -192,15 +181,21 @@ int initialize_groups(char *user, uid_t uid, gid_t gid) Create the SID list for this user. ****************************************************************************/ -void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid_t *groups) +NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) { + NT_USER_TOKEN *token; DOM_SID *psids; int i; + if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) + return NULL; + ZERO_STRUCTP(token); - if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) - return; + if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) { + free(token); + return NULL; + } psids = token->user_sids; @@ -211,6 +206,8 @@ void setup_nt_token(NT_USER_TOKEN *token, uid_t uid, gid_t gid, int ngroups, gid for (i = 0; i < ngroups; i++) gid_to_sid( &psids[i+2], groups[i]); + + return token; } /**************************************************************************** @@ -258,7 +255,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, get_current_groups( &vuser->n_groups, &vuser->groups); /* Create an NT_USER_TOKEN struct for this user. */ - setup_nt_token(&vuser->nt_user_token, uid,gid, vuser->n_groups, vuser->groups); + vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups); DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); -- cgit From 06e4f11acd3aedd6c8e4adf365932a01eca902b8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 4 Aug 2000 00:59:09 +0000 Subject: Fixed up the user/group contexts when using authenticated pipes. Added a become_root()/unbecome_root() (push/pop security context) around the initgroups() call to ensure it would succeed. Hmmm - I wonder if this call being done as non-root might explain any "group access" bugs we've had in the past.... Jeremy. (This used to be commit 06a65972e872f37d88b84f22ea714feebd38f6c0) --- source3/smbd/password.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9af7d3b1e9..4aa753c022 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -163,8 +163,9 @@ char *validated_domain(uint16 vuid) Initialize the groups a user belongs to. ****************************************************************************/ -int initialize_groups(char *user, uid_t uid, gid_t gid) +BOOL initialize_groups(char *user, uid_t uid, gid_t gid) { + become_root(); if (initgroups(user,gid) == -1) { DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); if (getuid() == 0) { @@ -172,9 +173,11 @@ int initialize_groups(char *user, uid_t uid, gid_t gid) DEBUG(0,("This is probably a problem with the account %s\n", user)); } } - return -1; + unbecome_root(); + return False; } - return 0; + become_root(); + return True; } /**************************************************************************** -- cgit From 04de6d02584aa431cbd99e057407ffeb3bdc413d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 8 Aug 2000 23:49:26 +0000 Subject: Found the sec_ctx_stack overflow - a become_root() should have been an unbecome_root() - typo. Jeremy. (This used to be commit ebb160663ed55e44e44f1c3d17eb077a32c2ffb9) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4aa753c022..2b43f0baf4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -176,7 +176,7 @@ BOOL initialize_groups(char *user, uid_t uid, gid_t gid) unbecome_root(); return False; } - become_root(); + unbecome_root(); return True; } -- cgit From d12f3fea7529c03b6a3650e7aa8b4b47a445d548 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Aug 2000 06:46:53 +0000 Subject: Merge from appliance branch. (This used to be commit 567b0095b1b8393b3b1e32533aa2860ab3dbfa47) --- source3/smbd/password.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2b43f0baf4..3545f41dff 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -188,6 +188,7 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) { NT_USER_TOKEN *token; DOM_SID *psids; + int i, psid_ndx = 0; int i; if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) @@ -202,11 +203,19 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) psids = token->user_sids; + token->num_sids = 2; token->num_sids = ngroups + 2; uid_to_sid( &psids[0], uid); gid_to_sid( &psids[1], gid); + for (i = 0; i < ngroups; i++) { + if (groups[i] != gid) { + gid_to_sid( &psids[psid_ndx+2], groups[i]); + psid_ndx++; + token->num_sids++; + } + } for (i = 0; i < ngroups; i++) gid_to_sid( &psids[i+2], groups[i]); @@ -254,6 +263,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Find all the groups this uid is in and store them. Used by become_user() */ + initialise_groups(unix_name, uid, gid); initialize_groups(unix_name, uid, gid); get_current_groups( &vuser->n_groups, &vuser->groups); -- cgit From 66cc9787ef6b8d0f2c3161a09dda6e4ffa029739 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 28 Aug 2000 07:25:18 +0000 Subject: Merge bug - still getting used to dirdiff. (This used to be commit cb717b4a2bb55eb2ff008e59203ebfeac6c5ab9f) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3545f41dff..baa2823732 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -189,7 +189,6 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) NT_USER_TOKEN *token; DOM_SID *psids; int i, psid_ndx = 0; - int i; if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) return NULL; -- cgit From 7d93eb3483029c9edd2c7b6361d514a7a3ec4e94 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 28 Aug 2000 20:45:00 +0000 Subject: smbd/password.c: Fixed typo in Tim's new code that caused insure overrun error. smbd/reply.c: Fixed lowercasing UNIX character set problem. Jeremy. (This used to be commit 2b6e3ed7a6447d40d9dd7e9b5c286b1aabe4730d) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index baa2823732..9e59815e52 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -203,7 +203,6 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) psids = token->user_sids; token->num_sids = 2; - token->num_sids = ngroups + 2; uid_to_sid( &psids[0], uid); gid_to_sid( &psids[1], gid); -- cgit From a1f66a820d78244fcab960fe33999c76cc1d65c5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Sep 2000 01:06:39 +0000 Subject: Fix for the SID history problem when using a Win2k domain controller with security=domain. Also fixed to dynamically allocate the SIDs and GIDs. Jeremy. (This used to be commit 2b1f66eb82f05fe0b85ac5b4916e32847b8de675) --- source3/smbd/password.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9e59815e52..6d3a2d1a31 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1487,19 +1487,12 @@ BOOL domain_client_validate( char *user, char *domain, cli_ulogoff(&cli); cli_shutdown(&cli); - /* unused, so delete here. */ - if (info3.gids != NULL) - free (info3.gids); - if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL)) *user_exists = False; return False; } - /* unused, so delete here. */ - if (info3.gids != NULL) - free (info3.gids); /* * Here, if we really want it, we have lots of info about the user in info3. */ @@ -1521,6 +1514,10 @@ BOOL domain_client_validate( char *user, char *domain, } #endif /* 0 */ + /* Note - once the cli stream is shutdown the mem_ctx used + to allocate the other_sids and gids structures has been deleted - so + these pointers are no longer valid..... */ + cli_nt_session_close(&cli); cli_ulogoff(&cli); cli_shutdown(&cli); -- cgit From 45d30f72ffc48ed06907f8eba1beed61be81f783 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 7 Sep 2000 08:43:05 +0000 Subject: Hopefully this should fix the primary group permission problem. (This used to be commit 2f33ec41ac1d3243340455b6c3a6cea22d267f14) --- source3/smbd/password.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6d3a2d1a31..fe3c9fea0f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -214,8 +214,6 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) token->num_sids++; } } - for (i = 0; i < ngroups; i++) - gid_to_sid( &psids[i+2], groups[i]); return token; } -- cgit From 7ec53a14b149bcf90cf38548a0d9044286b3e3bb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Sep 2000 19:51:38 +0000 Subject: With John Reilly help tracking it down - fixed a *nasty* bug when authorising logins. If a user connected to a share as guest, then the snum was getting flagged as "force guest", meaning that all subsequent connections to it, even under a different vuid, would be bounced to guest. This explains several very hard to reproduce access denied bugs, and as the NT client also has bugs in that it will sometimes erroneously use guest instead of the correct vuid on an IPC$ connection lead to a *very* hard problem to find. This fix should be propagated into all branches (TNG/Applience take note) and I'll also make a separate patch availalble on the samba-technical list. Jeremy. (This used to be commit 0264fdafe909cf9e995df3ae7b64bedbe0b4e8a1) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fe3c9fea0f..da01cf4f37 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -818,7 +818,6 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, else DEBUG(0,("Invalid guest account %s??\n",guestname)); *guest = True; - *force = True; } if (ok && !user_ok(user,snum)) -- cgit From 56d514235ed16d3cb6b3682afa6980eb3455c50d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 5 Oct 2000 22:51:57 +0000 Subject: Fix for null passwords being allowed bug. Jeremy. (This used to be commit d4d55488397832df35b558564c263a307b0bb629) --- source3/smbd/password.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index da01cf4f37..2f720db9c1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -514,10 +514,14 @@ BOOL pass_check_smb(char *user, char *domain, return(False); } - if (lm_pwd[0] == '\0' && (smb_pass->acct_ctrl & ACB_PWNOTREQ) && lp_null_passwords()) - { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name)); - return(True); + if (smb_pass->acct_ctrl & ACB_PWNOTREQ) { + if (lp_null_passwords()) { + DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name)); + return(True); + } else { + DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", smb_pass->smb_name)); + return(False); + } } if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd)) -- cgit From 7c4c781df2ef3d0ef772fdde215c72ded7445ab8 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 11 Oct 2000 04:54:01 +0000 Subject: Remove duplicate group initialisation function. Don't initialise groups twice. (This used to be commit 5375261152b28a65de18e817c75cab79c2f556b8) --- source3/smbd/password.c | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2f720db9c1..55c7f0709b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -159,27 +159,6 @@ char *validated_domain(uint16 vuid) } -/**************************************************************************** - Initialize the groups a user belongs to. -****************************************************************************/ - -BOOL initialize_groups(char *user, uid_t uid, gid_t gid) -{ - become_root(); - if (initgroups(user,gid) == -1) { - DEBUG(0,("Unable to initgroups. Error was %s\n", strerror(errno) )); - if (getuid() == 0) { - if (gid < 0 || gid > 32767 || uid < 0 || uid > 32767) { - DEBUG(0,("This is probably a problem with the account %s\n", user)); - } - } - unbecome_root(); - return False; - } - unbecome_root(); - return True; -} - /**************************************************************************** Create the SID list for this user. ****************************************************************************/ @@ -260,7 +239,6 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Find all the groups this uid is in and store them. Used by become_user() */ initialise_groups(unix_name, uid, gid); - initialize_groups(unix_name, uid, gid); get_current_groups( &vuser->n_groups, &vuser->groups); /* Create an NT_USER_TOKEN struct for this user. */ -- cgit From 9fede0dc0dbad51528cd1384023d24549c3f0ba4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 13 Nov 2000 23:03:34 +0000 Subject: Large commit which restructures the local password storage API. Currently the only backend which works is smbpasswd (tdb, LDAP, and NIS+) are broken, but they were somewhat broken before. :) The following functions implement the storage manipulation interface /*The following definitions come from passdb/pdb_smbpasswd.c */ BOOL pdb_setsampwent (BOOL update); void pdb_endsampwent (void); SAM_ACCOUNT* pdb_getsampwent (void); SAM_ACCOUNT* pdb_getsampwnam (char *username); SAM_ACCOUNT* pdb_getsampwuid (uid_t uid); SAM_ACCOUNT* pdb_getsampwrid (uint32 rid); BOOL pdb_add_sam_account (SAM_ACCOUNT *sampass); BOOL pdb_update_sam_account (SAM_ACCOUNT *sampass, BOOL override); BOOL pdb_delete_sam_account (char* username); There is also a host of pdb_set..() and pdb_get..() functions for manipulating SAM_ACCOUNT struct members. Note that the struct passdb_ops {} has gone away. Also notice that struct smb_passwd (formally in smb.h) has been moved to passdb/pdb_smbpasswd.c and is not accessed outisde of static internal functions in this file. All local password searches should make use of the the SAM_ACCOUNT struct and the previously mentioned functions. I'll write some documentation for this later. The next step is to fix the TDB passdb backend, then work on spliting the backends out into share libraries, and finally get the LDAP backend going. What works and may not: o domain logons from Win9x works o domain logons from WinNT 4 works o user and group enumeration as implemented by Tim works o file and print access works o changing password from Win9x & NT ummm...i'll fix this tonight :) If I broke anything else, just yell and I'll fix it. I think it should be fairly quite. -- jerry (This used to be commit 0b92d0838ebdbe24f34f17e313ecbf61a0301389) --- source3/smbd/password.c | 104 ++++++++++++++++++++++++++---------------------- 1 file changed, 57 insertions(+), 47 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 55c7f0709b..934b3155f3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -289,15 +289,15 @@ update the encrypted smbpasswd file from the plaintext username and password *****************************************************************************/ static BOOL update_smbpassword_file(char *user, char *password) { - struct smb_passwd *smbpw; - BOOL ret; + SAM_ACCOUNT *sampass = NULL; + BOOL ret; become_root(); - smbpw = getsmbpwnam(user); + sampass = pdb_getsampwnam(user); unbecome_root(); - if(smbpw == NULL) { - DEBUG(0,("getsmbpwnam returned NULL\n")); + if(sampass == NULL) { + DEBUG(0,("pdb_getsampwnam returned NULL\n")); return False; } @@ -305,11 +305,11 @@ static BOOL update_smbpassword_file(char *user, char *password) * Remove the account disabled flag - we are updating the * users password from a login. */ - smbpw->acct_ctrl &= ~ACB_DISABLED; + pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED); /* Here, the flag is one, because we want to ignore the XXXXXXX'd out password */ - ret = change_oem_password( smbpw, password, True); + ret = change_oem_password( sampass, password, True); if (ret == False) { DEBUG(3,("change_oem_password returned False\n")); } @@ -317,10 +317,6 @@ static BOOL update_smbpassword_file(char *user, char *password) return ret; } - - - - /**************************************************************************** core of smb password checking routine. ****************************************************************************/ @@ -367,19 +363,22 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha Do a specific test for an smb password being correct, given a smb_password and the lanman and NT responses. ****************************************************************************/ -BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], +BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8], uchar lm_pass[24], uchar nt_pass[24]) { uchar challenge[8]; + char* user_name; + BYTE *nt_pw, *lm_pw; - if (!lm_pass || !smb_pass) return(False); + if (!lm_pass || !sampass) + return(False); - DEBUG(4,("Checking SMB password for user %s\n", - smb_pass->smb_name)); + user_name = pdb_get_username(sampass); + + DEBUG(4,("Checking SMB password for user %s\n",user_name)); - if(smb_pass->acct_ctrl & ACB_DISABLED) { - DEBUG(1,("account for user %s was disabled.\n", - smb_pass->smb_name)); + if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { + DEBUG(1,("account for user %s was disabled.\n", user_name)); return(False); } @@ -398,35 +397,36 @@ BOOL smb_password_ok(struct smb_passwd *smb_pass, uchar chal[8], memcpy(challenge, chal, 8); } - if ((Protocol >= PROTOCOL_NT1) && (smb_pass->smb_nt_passwd != NULL)) { + nt_pw = pdb_get_nt_passwd(sampass); + + if ((Protocol >= PROTOCOL_NT1) && (nt_pw != NULL)) { /* We have the NT MD4 hash challenge available - see if we can use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check((char *)nt_pass, - (uchar *)smb_pass->smb_nt_passwd, - challenge)) { + if (smb_password_check((char *)nt_pass, (uchar *)nt_pw, challenge)) + { DEBUG(4,("NT MD4 password check succeeded\n")); return(True); } DEBUG(4,("NT MD4 password check failed\n")); } - /* Try against the lanman password. smb_pass->smb_passwd == NULL means - no password, allow access. */ + /* Try against the lanman password. pdb_get_lanman_passwd(sampass) == NULL + means no password, allow access. */ DEBUG(4,("Checking LM MD4 password\n")); - if((smb_pass->smb_passwd == NULL) && - (smb_pass->acct_ctrl & ACB_PWNOTREQ)) { - DEBUG(4,("no password required for user %s\n", - smb_pass->smb_name)); + lm_pw = pdb_get_lanman_passwd(sampass); + + if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) + { + DEBUG(4,("no password required for user %s\n",user_name)); return True; } - if((smb_pass->smb_passwd != NULL) && - smb_password_check((char *)lm_pass, - (uchar *)smb_pass->smb_passwd, challenge)) { + if((lm_pw != NULL) && smb_password_check((char *)lm_pass,(uchar *)lm_pw, challenge)) + { DEBUG(4,("LM MD4 password check succeeded\n")); return(True); } @@ -443,18 +443,19 @@ SMB hash return True if the password is correct, False otherwise ****************************************************************************/ -BOOL pass_check_smb(char *user, char *domain, - uchar *chal, uchar *lm_pwd, uchar *nt_pwd, - struct passwd *pwd) +BOOL pass_check_smb(char *user, char *domain, uchar *chal, + uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd) { struct passwd *pass; - struct smb_passwd *smb_pass; + SAM_ACCOUNT *sampass; if (!lm_pwd || !nt_pwd) { return(False); } + /* FIXME! this code looks to be unnecessary now that the passdb + validates that the username exists and has a valid uid */ if (pwd != NULL && user == NULL) { pass = (struct passwd *) pwd; @@ -462,6 +463,8 @@ BOOL pass_check_smb(char *user, char *domain, } else { + /* I don't get this call here. I think it should be moved. + Need to check on it. --jerry */ pass = smb_getpwnam(user,True); } @@ -471,38 +474,45 @@ BOOL pass_check_smb(char *user, char *domain, return(False); } - smb_pass = getsmbpwnam(user); - - if (smb_pass == NULL) + /* get the account information */ + sampass = pdb_getsampwnam(user); + if (sampass == NULL) { - DEBUG(1,("Couldn't find user '%s' in smb_passwd file.\n", user)); + DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user)); return(False); } /* Quit if the account was disabled. */ - if(smb_pass->acct_ctrl & ACB_DISABLED) { + if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { DEBUG(1,("Account for user '%s' was disabled.\n", user)); return(False); } - /* Ensure the uid's match */ + /* Ensure the uid's match + FIXME! This also seems unnecessary --jerry */ +#if 0 /* GWC */ if (smb_pass->smb_userid != pass->pw_uid) { DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user)); return(False); } +#endif - if (smb_pass->acct_ctrl & ACB_PWNOTREQ) { - if (lp_null_passwords()) { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", smb_pass->smb_name)); + if (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) + { + if (lp_null_passwords()) + { + DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user)); return(True); - } else { - DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", smb_pass->smb_name)); + } + else + { + DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user)); return(False); } } - if (smb_password_ok(smb_pass, chal, lm_pwd, nt_pwd)) + if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd)) { return(True); } -- cgit From 14067f9c9ce1ea4d0301c0c8c7ba71278234d1bb Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 21 Nov 2000 06:05:08 +0000 Subject: combined 2 if statments which used the same condition -- jerry (This used to be commit 445fd1dbd8bb93f56f20b5dd9e9d5b018147b21d) --- source3/smbd/password.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 934b3155f3..a1df5bf7f0 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -326,11 +326,13 @@ BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned cha unsigned char p21[21]; unsigned char p24[24]; - if (part_passwd == NULL) + if (part_passwd == NULL) + { DEBUG(10,("No password set - allowing access\n")); - /* No password set - always true ! */ - if (part_passwd == NULL) + + /* No password set - always true ! */ return 1; + } memset(p21,'\0',21); memcpy(p21,part_passwd,16); -- cgit From 366bf693d21a5fe3020b8528ae879d9734e67231 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 28 Nov 2000 22:17:44 +0000 Subject: include/dlinklist.h: Added '{' '}' around DLIST_PROMOTE so it can be used as a single statement after an 'if'. Tracking this down took 4 hours from my life and ANDREW I WANT THEM BACK !!!!! :-). include/smb.h smbd/password.c: Fixed the bug veritas reported with realloc of the validated_users array growing without bounds. This is now a linked list as god (Andrew) intended :-). Jeremy. (This used to be commit 346f2f9206b9b4ed123e2a61c0a48de630397b8a) --- source3/smbd/password.c | 141 +++++++++++++++++++++++++++--------------------- 1 file changed, 81 insertions(+), 60 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a1df5bf7f0..48e4172ace 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -93,8 +93,9 @@ static BOOL last_challenge(unsigned char *challenge) } /* this holds info on user ids that are already validated for this VC */ -static user_struct *validated_users = NULL; -static int num_validated_users = 0; +static user_struct *validated_users; +static int next_vuid = VUID_OFFSET; +static int num_validated_vuids; /**************************************************************************** check if a uid has been validated, and return an pointer to the user_struct @@ -103,13 +104,21 @@ tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ user_struct *get_valid_user_struct(uint16 vuid) { - if (vuid == UID_FIELD_INVALID) - return NULL; - vuid -= VUID_OFFSET; - if ((vuid >= (uint16)num_validated_users) || - (validated_users[vuid].uid == (uid_t)-1) || (validated_users[vuid].gid == (gid_t)-1)) - return NULL; - return &validated_users[vuid]; + user_struct *usp; + int count=0; + + if (vuid == UID_FIELD_INVALID) + return NULL; + + for (usp=validated_users;usp;usp=usp->next,count++) { + if (vuid == usp->vuid) { + if (count > 10) + DLIST_PROMOTE(validated_users, usp); + return usp; + } + } + + return NULL; } /**************************************************************************** @@ -122,18 +131,12 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; - vuser->uid = (uid_t)-1; - vuser->gid = (gid_t)-1; - - /* same number of igroups as groups */ - vuser->n_groups = 0; - - if (vuser->groups) - free((char *)vuser->groups); - - vuser->groups = NULL; + DLIST_REMOVE(validated_users, vuser); + safe_free(vuser->groups); delete_nt_token(&vuser->nt_user_token); + safe_free(vuser); + num_validated_vuids--; } /**************************************************************************** @@ -206,58 +209,76 @@ tell random client vuid's (normally zero) from valid vuids. uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, char *domain,BOOL guest) { - user_struct *vuser; - struct passwd *pwfile; /* for getting real name from passwd file */ + user_struct *vuser = NULL; + user_struct *vsp; + struct passwd *pwfile; /* for getting real name from passwd file */ - /* Ensure no vuid gets registered in share level security. */ - if(lp_security() == SEC_SHARE) - return UID_FIELD_INVALID; + /* Ensure no vuid gets registered in share level security. */ + if(lp_security() == SEC_SHARE) + return UID_FIELD_INVALID; - validated_users = (user_struct *)Realloc(validated_users, - sizeof(user_struct)* - (num_validated_users+1)); - - if (!validated_users) { - DEBUG(0,("Failed to realloc users struct!\n")); - num_validated_users = 0; - return UID_FIELD_INVALID; - } + /* Limit allowed vuids to 16bits - VUID_OFFSET. */ + if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) + return UID_FIELD_INVALID; - vuser = &validated_users[num_validated_users]; - num_validated_users++; + if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) { + DEBUG(0,("Failed to malloc users struct!\n")); + return UID_FIELD_INVALID; + } - vuser->uid = uid; - vuser->gid = gid; - vuser->guest = guest; - fstrcpy(vuser->user.unix_name,unix_name); - fstrcpy(vuser->user.smb_name,requested_name); - fstrcpy(vuser->user.domain,domain); + ZERO_STRUCTP(vuser); - vuser->n_groups = 0; - vuser->groups = NULL; + DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)uid, (unsigned int)gid, + unix_name, requested_name, domain, guest )); - /* Find all the groups this uid is in and store them. - Used by become_user() */ - initialise_groups(unix_name, uid, gid); - get_current_groups( &vuser->n_groups, &vuser->groups); + /* Allocate a free vuid. Yes this is a linear search... :-) */ + while( (vsp = get_valid_user_struct(next_vuid)) != NULL ) { + next_vuid++; + /* Check for vuid wrap. */ + if (next_vuid == UID_FIELD_INVALID) + next_vuid = VUID_OFFSET; + } - /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups); + DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid )); - DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); + vuser->vuid = next_vuid; + vuser->uid = uid; + vuser->gid = gid; + vuser->guest = guest; + fstrcpy(vuser->user.unix_name,unix_name); + fstrcpy(vuser->user.smb_name,requested_name); + fstrcpy(vuser->user.domain,domain); - DEBUG(3, ("Clearing default real name\n")); - fstrcpy(vuser->user.full_name, ""); - if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); - fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } - } + vuser->n_groups = 0; + vuser->groups = NULL; + + /* Find all the groups this uid is in and store them. + Used by become_user() */ + initialise_groups(unix_name, uid, gid); + get_current_groups( &vuser->n_groups, &vuser->groups); + + /* Create an NT_USER_TOKEN struct for this user. */ + vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups); + + next_vuid++; + num_validated_vuids++; + + DLIST_ADD(validated_users, vuser); + + DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); + + DEBUG(3, ("Clearing default real name\n")); + fstrcpy(vuser->user.full_name, ""); + if (lp_unix_realname()) { + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); + fstrcpy(vuser->user.full_name, pwfile->pw_gecos); + } + } - memset(&vuser->dc, '\0', sizeof(vuser->dc)); + memset(&vuser->dc, '\0', sizeof(vuser->dc)); - return (uint16)((num_validated_users - 1) + VUID_OFFSET); + return vuser->vuid; } -- cgit From a1f4e6e9273d5cf98cfed330c02d9a41886edf44 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 6 Dec 2000 03:22:44 +0000 Subject: Print debug if domain_client_validate() cannot fetch the trust account password (say for example if the tdb file format has changed). (-: (This used to be commit 447fbb38a857a7e97cf2a99022576521c71a4512) --- source3/smbd/password.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 48e4172ace..f759f3b781 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1444,7 +1444,8 @@ BOOL domain_client_validate( char *user, char *domain, */ if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) { - return False; + DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", lp_workgroup())); + return False; } /* -- cgit From cf5b71994d6cdb2f81c390579f4a0e676926c6b9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 7 Dec 2000 19:26:04 +0000 Subject: file_lines_load/file_lines_pload can now optionally convert unix_to_dos() on read. Jeremy. (This used to be commit 76b8dd376d13eb4469417be217c966d54d333367) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f759f3b781..f9657eb9ee 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -854,7 +854,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) int plus_allowed = 1; char *file_host; char *file_user; - char **lines = file_lines_load(equiv_file, NULL); + char **lines = file_lines_load(equiv_file, NULL, False); int i; DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); -- cgit From 0f1ead1c93f1dcbbb3f108e4d879778d6b00d82e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Dec 2000 19:21:09 +0000 Subject: Removed unused auto (IRIX compiler warning). Jeremy. (This used to be commit 63e2ebc4272cd8bc52ea80e1e12996ab273b8ea4) --- source3/smbd/password.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f9657eb9ee..7232bffd11 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -210,7 +210,6 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, char *domain,BOOL guest) { user_struct *vuser = NULL; - user_struct *vsp; struct passwd *pwfile; /* for getting real name from passwd file */ /* Ensure no vuid gets registered in share level security. */ @@ -232,7 +231,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, unix_name, requested_name, domain, guest )); /* Allocate a free vuid. Yes this is a linear search... :-) */ - while( (vsp = get_valid_user_struct(next_vuid)) != NULL ) { + while( get_valid_user_struct(next_vuid) != NULL ) { next_vuid++; /* Check for vuid wrap. */ if (next_vuid == UID_FIELD_INVALID) -- cgit From 276364e2a4cee00f4521845347a0b0a371f6b0e6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Dec 2000 02:36:14 +0000 Subject: Removed the special casing of SIDs in se_access_check. This is now done (correctly) when the NT_USER_TOKEN is *created*. Jeremy. (This used to be commit 27d72ed1cf8ece2bede812341279ba5a7262ace4) --- source3/smbd/password.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 7232bffd11..193653a867 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -166,37 +166,56 @@ char *validated_domain(uint16 vuid) Create the SID list for this user. ****************************************************************************/ -NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups) +NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest) { + extern DOM_SID global_sid_World; + extern DOM_SID global_sid_Network; + extern DOM_SID global_sid_Builtin_Guests; + extern DOM_SID global_sid_Authenticated_Users; NT_USER_TOKEN *token; DOM_SID *psids; int i, psid_ndx = 0; + size_t num_sids = 0; if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) return NULL; ZERO_STRUCTP(token); - if ((token->user_sids = (DOM_SID *)malloc( (ngroups + 2)*sizeof(DOM_SID))) == NULL) { + /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */ + num_sids = 5 + ngroups; + + if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { free(token); return NULL; } psids = token->user_sids; - token->num_sids = 2; + sid_copy( &psids[psid_ndx++], &global_sid_World); + sid_copy( &psids[psid_ndx++], &global_sid_Network); - uid_to_sid( &psids[0], uid); - gid_to_sid( &psids[1], gid); + /* + * The only difference between guest and "anonymous" (which we + * don't really support) is the addition of Authenticated_Users. + */ + + if (is_guest) + sid_copy( &psids[psid_ndx++], &global_sid_Builtin_Guests); + else + sid_copy( &psids[psid_ndx++], &global_sid_Authenticated_Users); + + uid_to_sid( &psids[psid_ndx++], uid); + gid_to_sid( &psids[psid_ndx++], gid); for (i = 0; i < ngroups; i++) { if (groups[i] != gid) { - gid_to_sid( &psids[psid_ndx+2], groups[i]); - psid_ndx++; - token->num_sids++; + gid_to_sid( &psids[psid_ndx++], groups[i]); } } + token->num_sids = psid_ndx; + return token; } @@ -257,7 +276,7 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, get_current_groups( &vuser->n_groups, &vuser->groups); /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups); + vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups, guest); next_vuid++; num_validated_vuids++; -- cgit From cade42c05b4d050f0b222594e1d1ccc13097c339 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Dec 2000 20:41:02 +0000 Subject: Fixed bug noticed by JF. se_access_check needs user SID as first in token. Jeremy. (This used to be commit f0d7867801e3f78bfc55fdb36ca965e35457f51b) --- source3/smbd/password.c | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 193653a867..1924bf3217 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -192,28 +192,41 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, psids = token->user_sids; - sid_copy( &psids[psid_ndx++], &global_sid_World); - sid_copy( &psids[psid_ndx++], &global_sid_Network); - /* - * The only difference between guest and "anonymous" (which we - * don't really support) is the addition of Authenticated_Users. + * Note - user SID *MUST* be first in token ! + * se_access_check depends on this. */ - if (is_guest) - sid_copy( &psids[psid_ndx++], &global_sid_Builtin_Guests); - else - sid_copy( &psids[psid_ndx++], &global_sid_Authenticated_Users); - uid_to_sid( &psids[psid_ndx++], uid); + + /* + * Primary group SID is second in token. Convention. + */ + gid_to_sid( &psids[psid_ndx++], gid); + /* Now add the group SIDs. */ + for (i = 0; i < ngroups; i++) { if (groups[i] != gid) { gid_to_sid( &psids[psid_ndx++], groups[i]); } } + /* + * Finally add the "standard" SIDs. + * The only difference between guest and "anonymous" (which we + * don't really support) is the addition of Authenticated_Users. + */ + + sid_copy( &psids[psid_ndx++], &global_sid_World); + sid_copy( &psids[psid_ndx++], &global_sid_Network); + + if (is_guest) + sid_copy( &psids[psid_ndx++], &global_sid_Builtin_Guests); + else + sid_copy( &psids[psid_ndx++], &global_sid_Authenticated_Users); + token->num_sids = psid_ndx; return token; -- cgit From 7bf9d8ce4bb7e96a4c72f674e21d015b1ef1481e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 19 Dec 2000 23:57:48 +0000 Subject: Fixed bug found by Gerald. If a Samba server joins a domain and is set to search for a DC to authenticate to using the "*" syntax than ensure that for the first hour after the password change is searches for the PDC using the 1B name not the 1C name as domain replication may not have occured. Jeremy. (This used to be commit c25533de9918ed9b0c79fd039e11d1b79f513db0) --- source3/smbd/password.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1924bf3217..c2bcac339e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1344,14 +1344,27 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un We have been asked to dynamcially determine the IP addresses of the PDC and BDC's for this DOMAIN, and query them in turn. ************************************************************************/ -static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd) +static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd, time_t last_change_time) { struct in_addr *ip_list = NULL; int count = 0; int i; BOOL connected_ok = False; + time_t time_now = time(NULL); + BOOL use_pdc_only = False; - if (!get_dc_list(lp_workgroup(), &ip_list, &count)) + /* + * If the time the machine password has changed + * was less than an hour ago then we need to contact + * the PDC only, as we cannot be sure domain replication + * has yet taken place. Bug found by Gerald (way to go + * Gerald !). JRA. + */ + + if (time_now - last_change_time < 3600) + use_pdc_only = True; + + if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count)) return False; /* @@ -1423,6 +1436,7 @@ BOOL domain_client_validate( char *user, char *domain, struct cli_state cli; uint32 smb_uid_low; BOOL connected_ok = False; + time_t last_change_time; if(user_exists != NULL) *user_exists = True; /* Only set false on a very specific error. */ @@ -1473,7 +1487,7 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password for our primary domain */ - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, NULL)) + if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time)) { DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", lp_workgroup())); return False; @@ -1501,7 +1515,7 @@ BOOL domain_client_validate( char *user, char *domain, while (!connected_ok && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { if(strequal(remote_machine, "*")) { - connected_ok = find_connect_pdc(&cli, trust_passwd); + connected_ok = find_connect_pdc(&cli, trust_passwd, last_change_time); } else { connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); } -- cgit From 23807f2b308e80a1e325c8fd2bddeec3e2e15bc5 Mon Sep 17 00:00:00 2001 From: David O'Neill Date: Thu, 4 Jan 2001 19:27:08 +0000 Subject: Changes from APPLIANCE_HEAD: source/Makefile.in - changes to ctags and etags rules that somehow got lost along the way. source/include/proto.h - make proto source/smbd/sec_ctx.c source/smbd/password.c - merge debugs for debugging user groups and NT token stuff. source/lib/util_str.c - capitalise domain name returned from parse_domain_user() source/nsswitch/wb_client.c - fix broken conditional in debug statement. source/include/rpc_secdes.h source/include/rpc_spoolss.h source/printing/nt_printing.c source/lib/util_seaccess.c - fix printer permission bugs related to ACE masks for printers. This adds mapping of generic access rights to object specific rights for NT printers. Still need to work out whether or not to ignore ACEs with certain flags set, though. See comments in util_seaccess.c:check_ace() for details. source/printing/nt_printing.c source/printing/printing.c - use PRINTER_ACCESS_ADMINISTER instead of JOB_ACCESS_ADMINISTER until we sort out printer/printjob permission stuff. (This used to be commit 1dba9c5cd1e6389734c648f6903abcb7c8d5b2f0) --- source3/smbd/password.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c2bcac339e..69ba042155 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -176,6 +176,7 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, DOM_SID *psids; int i, psid_ndx = 0; size_t num_sids = 0; + fstring sid_str; if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) return NULL; @@ -229,6 +230,13 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, token->num_sids = psid_ndx; + /* Dump list of sids in token */ + + for (i = 0; i < token->num_sids; i++) { + DEBUG(5, ("user token sid %s\n", + sid_to_string(sid_str, &token->user_sids[i]))); + } + return token; } -- cgit From 5aef8a21c6e3cd690afb11d2d69d2e9bac25b6b4 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 25 Jan 2001 02:59:13 +0000 Subject: Fixes from appliance-head for pdc searches. Jeremy. (This used to be commit d04ed97ecab846def8467f313a71ef0e5c4005f6) --- source3/smbd/password.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 69ba042155..cdf3e28b03 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1211,16 +1211,31 @@ use this machine as the password server.\n")); given a name or IP address. ************************************************************************/ -static BOOL connect_to_domain_password_server(struct cli_state *pcli, char *remote_machine, +static BOOL connect_to_domain_password_server(struct cli_state *pcli, + char *server, unsigned char *trust_passwd) { struct in_addr dest_ip; + fstring remote_machine; if(cli_initialise(pcli) == False) { DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); return False; } + if (is_ipaddress(server)) { + struct in_addr to_ip; + + if (!inet_aton(server, &to_ip) || + !name_status_find(0x20, to_ip, remote_machine)) { + DEBUG(1, ("connect_to_domain_password_server: Can't " + "resolve name for IP %s\n", server)); + return False; + } + } else { + fstrcpy(remote_machine, server); + } + standard_sub_basic(remote_machine); strupper(remote_machine); -- cgit From 607ea0d6fa00b5a9f1dea0542c039411e60f0db4 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 8 Feb 2001 18:41:01 +0000 Subject: replaced inet_aton() with inet_addr() to keep Solaris from complaining. jerry (This used to be commit 2b18c4484313e77d98c8a7524cf9f5cc2c924dc2) --- source3/smbd/password.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index cdf3e28b03..311a019506 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1225,10 +1225,16 @@ static BOOL connect_to_domain_password_server(struct cli_state *pcli, if (is_ipaddress(server)) { struct in_addr to_ip; + + /* we shouldn't have 255.255.255.255 forthe IP address of + a password server anyways */ + if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) { + DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server)); + return False; + } - if (!inet_aton(server, &to_ip) || - !name_status_find(0x20, to_ip, remote_machine)) { - DEBUG(1, ("connect_to_domain_password_server: Can't " + if (!name_status_find(0x20, to_ip, remote_machine)) { + DEBUG(0, ("connect_to_domain_password_server: Can't " "resolve name for IP %s\n", server)); return False; } -- cgit From da3053048c3d224a20d6383ac6682d31059cd46c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:32:10 +0000 Subject: Merge of new 2.2 code into HEAD (Gerald I hate you :-) :-). Allows new SAMR RPC code to merge with new passdb code. Currently rpcclient doesn't compile. I'm working on it... Jeremy. (This used to be commit 0be41d5158ea4e645e93e8cd30617c038416e549) --- source3/smbd/password.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 311a019506..849aa87a75 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1,5 +1,3 @@ -#define OLD_NTDOMAIN 1 - /* Unix SMB/Netbios implementation. Version 1.9. @@ -1610,5 +1608,3 @@ BOOL domain_client_validate( char *user, char *domain, cli_shutdown(&cli); return True; } - -#undef OLD_NTDOMAIN -- cgit From a2e5dbb1120e726ba80b00a159dad1a1ca2e3a18 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 00:51:54 +0000 Subject: Remove "BYTE" - we already have uint8 - don't need more conflicts with system header files... Jeremy. (This used to be commit 31e0ce310ec38b3a3a05b344d6450d442c6be471) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 849aa87a75..9731b4140c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -428,7 +428,7 @@ BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8], { uchar challenge[8]; char* user_name; - BYTE *nt_pw, *lm_pw; + uint8 *nt_pw, *lm_pw; if (!lm_pass || !sampass) return(False); -- cgit From b840dce67639b8d270eaac27b29d7392981f55bd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 11 Mar 2001 22:26:28 +0000 Subject: Moved cruft out of smb.h into ntdomain.h where it belongs. dc struct now in pipe struct (where used) rather than user_struct. Secured machine account password changing in srv_netlog_nt.c - ensure that only the given machine can change its own password. May need to free this up later for NT admin tools, but this is a fail-safe secure position for now. Jeremy. (This used to be commit 46b12f2275dcd4b3114085160cd456441f9e921e) --- source3/smbd/password.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9731b4140c..12f7385f06 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -313,8 +313,6 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, } } - memset(&vuser->dc, '\0', sizeof(vuser->dc)); - return vuser->vuid; } -- cgit From bcdb9496e81c4d00a522ce57406dec08f6df9b34 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Mar 2001 00:24:40 +0000 Subject: Bail out early if null passwords and lp_null_passwords not set. Jeremy. (This used to be commit 7c718fc85e3dbfaf0195e352d06a8c682a6036fc) --- source3/smbd/password.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 12f7385f06..fa973dd720 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -586,6 +586,11 @@ return True if the password is correct, False otherwise ****************************************************************************/ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) { + if ((pwlen == 0) && !lp_null_passwords()) { + DEBUG(4,("Null passwords not allowed.\n")); + return False; + } + if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { /* if 24 bytes long assume it is an encrypted password */ -- cgit From 9ce5a03ccbcc21c60a3dbc39b1dbd06b30655852 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 18 Apr 2001 16:41:04 +0000 Subject: merge from 2.2 (This used to be commit f52a5014ee325f9d91f266f88eac51b6136a75b9) --- source3/smbd/password.c | 50 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fa973dd720..6c0fe79845 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -110,8 +110,9 @@ user_struct *get_valid_user_struct(uint16 vuid) for (usp=validated_users;usp;usp=usp->next,count++) { if (vuid == usp->vuid) { - if (count > 10) - DLIST_PROMOTE(validated_users, usp); + if (count > 10) { + DLIST_PROMOTE(validated_users, usp); + } return usp; } } @@ -129,6 +130,8 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; + session_yield(vuid); + DLIST_REMOVE(validated_users, vuser); safe_free(vuser->groups); @@ -137,6 +140,20 @@ void invalidate_vuid(uint16 vuid) num_validated_vuids--; } +/**************************************************************************** +invalidate all vuid entries for this process +****************************************************************************/ +void invalidate_all_vuids(void) +{ + user_struct *usp, *next=NULL; + + for (usp=validated_users;usp;usp=next) { + next = usp->next; + + invalidate_vuid(usp->vuid); + } +} + /**************************************************************************** return a validated username ****************************************************************************/ @@ -244,8 +261,8 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest) +int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, + char *domain,BOOL guest) { user_struct *vuser = NULL; struct passwd *pwfile; /* for getting real name from passwd file */ @@ -305,12 +322,15 @@ uint16 register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); DEBUG(3, ("Clearing default real name\n")); - fstrcpy(vuser->user.full_name, ""); - if (lp_unix_realname()) { - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); - fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } + if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); + fstrcpy(vuser->user.full_name, pwfile->pw_gecos); + } + + if (!session_claim(vuser->vuid)) { + DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid)); + invalidate_vuid(vuser->vuid); + return -1; } return vuser->vuid; @@ -737,6 +757,13 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, BOOL *guest,BOOL *force,uint16 vuid) { BOOL ok = False; + user_struct *vuser = get_valid_user_struct(vuid); + + if (lp_security() > SEC_SHARE && !vuser) { + DEBUG(1,("authorise_login: refusing user %s with no session setup\n", + user)); + return False; + } *guest = False; @@ -760,9 +787,6 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { - - user_struct *vuser = get_valid_user_struct(vuid); - /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { ok = password_ok(user,password, pwlen, NULL); -- cgit From e277c08631316ccda875a09a67ebb220c495c5a9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 22 Apr 2001 07:20:24 +0000 Subject: Commit of a modified version of Andrew Bartlett's patch that removes the horrid utmp hostname parameter - now uses the client name instead. Also tidies up some of the unencrypted password checking when PAM is compiled in. FIXME ! An pam_accountcheck() is being called even when smb encrypted passwords are negotiated. Is this the correct thing to do when winbindd is running ! This needs *SEVERE* testing.... Jeremy. (This used to be commit 071c799f479dd25efdb9c41745fc8f2beea7b568) --- source3/smbd/password.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6c0fe79845..698c6a1356 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -606,24 +606,33 @@ return True if the password is correct, False otherwise ****************************************************************************/ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) { + BOOL ret; + if ((pwlen == 0) && !lp_null_passwords()) { DEBUG(4,("Null passwords not allowed.\n")); return False; } - if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) - { + if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { /* if 24 bytes long assume it is an encrypted password */ uchar challenge[8]; - if (!last_challenge(challenge)) - { + if (!last_challenge(challenge)) { DEBUG(0,("Error: challenge not done for user=%s\n", user)); return False; } - return pass_check_smb(user, global_myworkgroup, + ret = pass_check_smb(user, global_myworkgroup, challenge, (uchar *)password, (uchar *)password, pwd); + + /* + * Try with PAM (may not be compiled in - returns True if not. JRA). + * FIXME ! Should this be called if we're using winbindd ? What about + * non-local accounts ? JRA. + */ + + if (ret) + return pam_accountcheck(user); } return pass_check(user, password, pwlen, pwd, -- cgit From ae8418d0c400f6458c1eb0b79881fd02629e5acd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 23 Apr 2001 04:15:35 +0000 Subject: Added smb_ prefix to all Samba wrapper pam functions. Fixed off by one bug using StrnCpy instead of strdup(). Jeremy. (This used to be commit d4b1c0be2e700c86a4338bb497777f97e3c960a7) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 698c6a1356..ba882f2bf2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -632,7 +632,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) */ if (ret) - return pam_accountcheck(user); + return smb_pam_accountcheck(user); } return pass_check(user, password, pwlen, pwd, -- cgit From c3a999409db6a9e0d38928feb02ab6815bd28d57 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 30 Apr 2001 21:05:58 +0000 Subject: Based on an original PAM patch by Andrew Bartlett, re-written by me to remove global static PAM variables, and to tidy up the PAM internals code. Now looks like the rest of Samba. Still needs testing. Jeremy. (This used to be commit 1648ac64a75de74d1a1575eb49cccc4f75488bfa) --- source3/smbd/password.c | 44 +++++++++++++++++++------------------------- 1 file changed, 19 insertions(+), 25 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ba882f2bf2..03d96bebc0 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -453,25 +453,21 @@ BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8], user_name = pdb_get_username(sampass); - DEBUG(4,("Checking SMB password for user %s\n",user_name)); + DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",user_name)); if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { - DEBUG(1,("account for user %s was disabled.\n", user_name)); + DEBUG(1,("smb_password_ok: account for user %s was disabled.\n", user_name)); return(False); } - if (chal == NULL) - { - DEBUG(5,("use last SMBnegprot challenge\n")); - if (!last_challenge(challenge)) - { - DEBUG(1,("no challenge done - password failed\n")); + if (chal == NULL) { + DEBUG(5,("smb_password_ok: use last SMBnegprot challenge\n")); + if (!last_challenge(challenge)) { + DEBUG(1,("smb_password_ok: no challenge done - password failed\n")); return False; } - } - else - { - DEBUG(5,("challenge received\n")); + } else { + DEBUG(5,("smb_password_ok: challenge received\n")); memcpy(challenge, chal, 8); } @@ -482,35 +478,33 @@ BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8], use it (ie. does it exist in the smbpasswd file). */ DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check((char *)nt_pass, (uchar *)nt_pw, challenge)) - { - DEBUG(4,("NT MD4 password check succeeded\n")); + if (smb_password_check((char *)nt_pass, (uchar *)nt_pw, challenge)) { + DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); return(True); } - DEBUG(4,("NT MD4 password check failed\n")); + DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); } /* Try against the lanman password. pdb_get_lanman_passwd(sampass) == NULL means no password, allow access. */ - DEBUG(4,("Checking LM MD4 password\n")); - lm_pw = pdb_get_lanman_passwd(sampass); if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) { - DEBUG(4,("no password required for user %s\n",user_name)); + DEBUG(4,("smb_password_ok: no password required for user %s\n",user_name)); return True; } - if((lm_pw != NULL) && smb_password_check((char *)lm_pass,(uchar *)lm_pw, challenge)) - { - DEBUG(4,("LM MD4 password check succeeded\n")); - return(True); + if(lp_lanman_auth() && (lm_pw != NULL)) { + DEBUG(4,("smb_password_ok: Checking LM password\n")); + if(smb_password_check((char *)lm_pass,(uchar *)lm_pw, challenge)) { + DEBUG(4,("smb_password_ok: LM password check succeeded\n")); + return(True); + } + DEBUG(4,("smb_password_ok: LM password check failed\n")); } - DEBUG(4,("LM MD4 password check failed\n")); - return False; } -- cgit From 1f7a451c1e059b5a86e1e78debd582579aa7bcb7 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 4 May 2001 14:28:28 +0000 Subject: merge from 2.2 in password_ok() to ensure that we check the return code from smb_pam_accountcheck() (This used to be commit d5d6f01aaf8d344bb44dbe047c2f760ca220529e) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 03d96bebc0..5820afacc8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -626,7 +626,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) */ if (ret) - return smb_pam_accountcheck(user); + return (smb_pam_accountcheck(user) == NT_STATUS_NOPROBLEMO); } return pass_check(user, password, pwlen, pwd, -- cgit From f35157f39293f9fa240a28642c41708b55d301c8 Mon Sep 17 00:00:00 2001 From: Jean-François Micouleau Date: Fri, 4 May 2001 15:44:27 +0000 Subject: Big cleanup of passdb and backends. I did some basic tests but I have probably broken something. Notably the password changing. So don't cry ;-) J.F. (This used to be commit a4a4c02b12f030a3b9e6225b999c90689dfc4719) --- source3/smbd/password.c | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 5820afacc8..f42451dceb 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -368,12 +368,15 @@ static BOOL update_smbpassword_file(char *user, char *password) SAM_ACCOUNT *sampass = NULL; BOOL ret; + pdb_init_sam(&sampass); + become_root(); - sampass = pdb_getsampwnam(user); + ret = pdb_getsampwnam(sampass, user); unbecome_root(); - if(sampass == NULL) { + if(ret == False) { DEBUG(0,("pdb_getsampwnam returned NULL\n")); + pdb_clear_sam(sampass); return False; } @@ -390,6 +393,7 @@ static BOOL update_smbpassword_file(char *user, char *password) DEBUG(3,("change_oem_password returned False\n")); } + pdb_clear_sam(sampass); return ret; } @@ -519,7 +523,8 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd) { struct passwd *pass; - SAM_ACCOUNT *sampass; + SAM_ACCOUNT *sampass=NULL; + BOOL ret; if (!lm_pwd || !nt_pwd) { @@ -546,17 +551,21 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, return(False); } + pdb_init_sam(&sampass); + /* get the account information */ - sampass = pdb_getsampwnam(user); - if (sampass == NULL) + ret = pdb_getsampwnam(sampass, user); + if (ret == False) { DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user)); + pdb_clear_sam(sampass); return(False); } /* Quit if the account was disabled. */ if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { DEBUG(1,("Account for user '%s' was disabled.\n", user)); + pdb_clear_sam(sampass); return(False); } @@ -566,6 +575,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (smb_pass->smb_userid != pass->pw_uid) { DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user)); + pdb_clear_sam(sampass); return(False); } #endif @@ -575,21 +585,25 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (lp_null_passwords()) { DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user)); + pdb_clear_sam(sampass); return(True); } else { DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user)); + pdb_clear_sam(sampass); return(False); } } if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd)) { + pdb_clear_sam(sampass); return(True); } DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user)); + pdb_clear_sam(sampass); return False; } -- cgit From 998fcd3f1ea496c0799cf9259d93135e13b4875e Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 6 May 2001 20:56:14 +0000 Subject: Patch from David_Tiller@ccnotes.ccity.com finally applied now I've thought about it to stop account lockouts with "security=server" mode. Sorry for the delay David. Jeremy. (This used to be commit e8819715038ed49b07ed5639b1b88ad12e994b53) --- source3/smbd/password.c | 147 +++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 70 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f42451dceb..0bc21dbbd6 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1156,96 +1156,103 @@ BOOL server_validate(char *user, char *domain, char *pass, int passlen, char *ntpass, int ntpasslen) { - struct cli_state *cli; - static unsigned char badpass[24]; - static BOOL tested_password_server = False; - static BOOL bad_password_server = False; + struct cli_state *cli; + static unsigned char badpass[24]; + static fstring baduser; + static BOOL tested_password_server = False; + static BOOL bad_password_server = False; - cli = server_client(); + cli = server_client(); - if (!cli->initialised) { - DEBUG(1,("password server %s is not connected\n", cli->desthost)); - return(False); - } + if (!cli->initialised) { + DEBUG(1,("password server %s is not connected\n", cli->desthost)); + return(False); + } - if(badpass[0] == 0) - memset(badpass, 0x1f, sizeof(badpass)); + if(badpass[0] == 0) + memset(badpass, 0x1f, sizeof(badpass)); - if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { - /* - * Very unlikely, our random bad password is the same as the users - * password. */ - memset(badpass, badpass[0]+1, sizeof(badpass)); - } + if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { + /* + * Very unlikely, our random bad password is the same as the users + * password. + */ + memset(badpass, badpass[0]+1, sizeof(badpass)); + } - /* - * Attempt a session setup with a totally incorrect password. - * If this succeeds with the guest bit *NOT* set then the password - * server is broken and is not correctly setting the guest bit. We - * need to detect this as some versions of NT4.x are broken. JRA. - */ + if(baduser[0] == 0) { + fstrcpy(baduser, INVALID_USER_PREFIX); + fstrcat(baduser, global_myname); + } + + /* + * Attempt a session setup with a totally incorrect password. + * If this succeeds with the guest bit *NOT* set then the password + * server is broken and is not correctly setting the guest bit. We + * need to detect this as some versions of NT4.x are broken. JRA. + */ - if(!tested_password_server) { - if (cli_session_setup(cli, user, (char *)badpass, sizeof(badpass), - (char *)badpass, sizeof(badpass), domain)) { + if(!tested_password_server) { + if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass), + (char *)badpass, sizeof(badpass), domain)) { - /* - * We connected to the password server so we - * can say we've tested it. - */ - tested_password_server = True; + /* + * We connected to the password server so we + * can say we've tested it. + */ + tested_password_server = True; - if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { - DEBUG(0,("server_validate: password server %s allows users as non-guest \ + if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { + DEBUG(0,("server_validate: password server %s allows users as non-guest \ with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ + DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - cli_ulogoff(cli); + cli_ulogoff(cli); - /* - * Password server has the bug. - */ - bad_password_server = True; - return False; - } - cli_ulogoff(cli); - } - } else { + /* + * Password server has the bug. + */ + bad_password_server = True; + return False; + } + cli_ulogoff(cli); + } + } else { - /* - * We have already tested the password server. - * Fail immediately if it has the bug. - */ + /* + * We have already tested the password server. + * Fail immediately if it has the bug. + */ - if(bad_password_server) { - DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ + if(bad_password_server) { + DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ + DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ use this machine as the password server.\n")); - return False; - } - } + return False; + } + } - /* - * Now we know the password server will correctly set the guest bit, or is - * not guest enabled, we can try with the real password. - */ + /* + * Now we know the password server will correctly set the guest bit, or is + * not guest enabled, we can try with the real password. + */ - if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli->desthost)); - return False; - } + if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { + DEBUG(1,("password server %s rejected the password\n", cli->desthost)); + return False; + } - /* if logged in as guest then reject */ - if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); - cli_ulogoff(cli); - return(False); - } + /* if logged in as guest then reject */ + if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { + DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); + cli_ulogoff(cli); + return(False); + } - cli_ulogoff(cli); + cli_ulogoff(cli); - return(True); + return(True); } /*********************************************************************** -- cgit From 30c4c04c2f584857633ce7605555dcfb37a3e1af Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 7 May 2001 14:04:46 +0000 Subject: Patch from Simo: o sed 's/pdb_clear_sam/pdb_free_sam/g' o add pdb_reset_sam() o password changing should be ok now as well. (This used to be commit 96d0e7c3301ad990f6c83b9c216720cb32661fb5) --- source3/smbd/password.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0bc21dbbd6..01fc9cdd53 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -376,7 +376,7 @@ static BOOL update_smbpassword_file(char *user, char *password) if(ret == False) { DEBUG(0,("pdb_getsampwnam returned NULL\n")); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return False; } @@ -393,7 +393,7 @@ static BOOL update_smbpassword_file(char *user, char *password) DEBUG(3,("change_oem_password returned False\n")); } - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return ret; } @@ -558,14 +558,14 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (ret == False) { DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return(False); } /* Quit if the account was disabled. */ if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { DEBUG(1,("Account for user '%s' was disabled.\n", user)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return(False); } @@ -575,7 +575,7 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (smb_pass->smb_userid != pass->pw_uid) { DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return(False); } #endif @@ -585,25 +585,25 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, if (lp_null_passwords()) { DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return(True); } else { DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return(False); } } if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd)) { - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return(True); } DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user)); - pdb_clear_sam(sampass); + pdb_free_sam(sampass); return False; } -- cgit From 2d27d8c720b705e8ca9575682948c0750c1bb080 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 17 May 2001 06:08:49 +0000 Subject: Fixes to get pam_auth() functionality working again. (This used to be commit 083b74c743f0026693fa0fbe665ed08a3ac706b8) --- source3/smbd/password.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 01fc9cdd53..303ed783e9 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1416,8 +1416,6 @@ static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, un return connect_to_domain_password_server(pcli, dc_name, trust_passwd); } - - /*********************************************************************** We have been asked to dynamcially determine the IP addresses of the PDC and BDC's for this DOMAIN, and query them in turn. @@ -1491,17 +1489,16 @@ static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd return connected_ok; } - - /*********************************************************************** Do the same as security=server, but using NT Domain calls and a session - key from the machine password. + key from the machine password. If the server parameter is specified + use it, otherwise figure out a server from the 'password server' param. ************************************************************************/ BOOL domain_client_validate( char *user, char *domain, char *smb_apasswd, int smb_apasslen, char *smb_ntpasswd, int smb_ntpasslen, - BOOL *user_exists) + BOOL *user_exists, char *server) { unsigned char local_challenge[8]; unsigned char local_lm_response[24]; @@ -1541,7 +1538,7 @@ BOOL domain_client_validate( char *user, char *domain, * Not encrypted - do so. */ - DEBUG(3,("domain_client_validate: User passwords not in encrypted format.\n")); + DEBUG(5,("domain_client_validate: User passwords not in encrypted format.\n")); generate_random_buffer( local_challenge, 8, False); SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_response); @@ -1586,9 +1583,13 @@ BOOL domain_client_validate( char *user, char *domain, * PDC/BDC. Contact each in turn and try and authenticate. */ - pserver = lp_passwordserver(); - if (! *pserver) pserver = "*"; - p = pserver; + if (server) { + p = server; + } else { + pserver = lp_passwordserver(); + if (! *pserver) pserver = "*"; + p = pserver; + } while (!connected_ok && next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { -- cgit From 22242c5038008171631c2625b2fd8b6d4b991078 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 25 May 2001 07:36:58 +0000 Subject: i18n fix for domain_client_validate() (This used to be commit d6dcca7cc9bc5a1948c1b6126ca4f6cb9ccacc52) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 303ed783e9..35aaf10e06 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1562,7 +1562,7 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password for our primary domain */ - if (!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd, &last_change_time)) + if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time)) { DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", lp_workgroup())); return False; -- cgit From 63c7ca9d6263fca56e335eccfbad1d773af5a1c3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 31 May 2001 14:13:53 +0000 Subject: Fix debug statement so it doesn't use lp_workgroup() either. Jeremy. (This used to be commit 18e652a5e0d30d033be70e512cd94bf867507f64) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 35aaf10e06..51528be2b4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1564,7 +1564,7 @@ BOOL domain_client_validate( char *user, char *domain, */ if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time)) { - DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", lp_workgroup())); + DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", domain)); return False; } -- cgit From 1aa05a31ac9eb0987e641312195ed12c76476b27 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Thu, 14 Jun 2001 00:08:42 +0000 Subject: Fixed some return code checks for cli_initialise() from False to NULL. Spotted by Joe Doran (This used to be commit 3e3b9bc5380652d882c02e7286258f0aabcaf395) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 51528be2b4..d2059e7e20 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1267,7 +1267,7 @@ static BOOL connect_to_domain_password_server(struct cli_state *pcli, struct in_addr dest_ip; fstring remote_machine; - if(cli_initialise(pcli) == False) { + if(cli_initialise(pcli) == NULL) { DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); return False; } -- cgit From 100a54e221dd0712ab37daa5359b202d0a059090 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 22 Jun 2001 00:57:59 +0000 Subject: Andrew - please look this over. I've fixed a long standing (maybe 4-5 years old) bug when chainging a sessionsetup_and_X and tcon together. The wrong username was being entered into the tdb, even though the correct user was used for accessing files. This is related to the fact that authorise_login() is not used for sessionsetup, but only for tcon auths. Jeremy. (This used to be commit 0187cd6aef7586d7ad4bdc70c50f3f2e7c69519c) --- source3/smbd/password.c | 283 +++++++++++++++++++++++++----------------------- 1 file changed, 147 insertions(+), 136 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index d2059e7e20..6be2989881 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -765,171 +765,182 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) return(NULL); } - - /**************************************************************************** -check for authority to login to a service with a given username/password + Check for authority to login to a service with a given username/password. + Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ + BOOL authorise_login(int snum,char *user,char *password, int pwlen, BOOL *guest,BOOL *force,uint16 vuid) { - BOOL ok = False; - user_struct *vuser = get_valid_user_struct(vuid); + BOOL ok = False; + user_struct *vuser = get_valid_user_struct(vuid); - if (lp_security() > SEC_SHARE && !vuser) { - DEBUG(1,("authorise_login: refusing user %s with no session setup\n", - user)); - return False; - } - - *guest = False; - #if DEBUG_PASSWORD - DEBUG(100,("checking authorisation on user=%s pass=%s\n",user,password)); + DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", + user,password)); #endif - /* there are several possibilities: - 1) login as the given user with given password - 2) login as a previously registered username with the given password - 3) login as a session list username with the given password - 4) login as a previously validated user/password pair - 5) login as the "user =" user with given password - 6) login as the "user =" user with no password (guest connection) - 7) login as guest user with no password + *guest = False; + + if (GUEST_ONLY(snum)) + *force = True; - if the service is guest_only then steps 1 to 5 are skipped - */ + if (!GUEST_ONLY(snum) && (lp_security() > SEC_SHARE)) { - if (GUEST_ONLY(snum)) *force = True; + /* + * We should just use the given vuid from a sessionsetup_and_X. + */ - if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) - { - /* check the given username and password */ - if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL); - if (ok) DEBUG(3,("ACCEPTED: given username password ok\n")); - } + if (!vuser) { + DEBUG(1,("authorise_login: refusing user %s with no session setup\n", + user)); + return False; + } - /* check for a previously registered guest username */ - if (!ok && (vuser != 0) && vuser->guest) { - if (user_ok(vuser->user.unix_name,snum) && - password_ok(vuser->user.unix_name, password, pwlen, NULL)) { - fstrcpy(user, vuser->user.unix_name); - vuser->guest = False; - DEBUG(3,("ACCEPTED: given password with registered user %s\n", user)); - ok = True; + if (!vuser->guest && user_ok(vuser->user.unix_name,snum)) { + fstrcpy(user,vuser->user.unix_name); + *guest = False; + DEBUG(3,("authorise_login: ACCEPTED: validated uid ok as non-guest \ +(user=%s)\n", user)); + return True; + } } - } - + + /* there are several possibilities: + 1) login as the given user with given password + 2) login as a previously registered username with the given password + 3) login as a session list username with the given password + 4) login as a previously validated user/password pair + 5) login as the "user =" user with given password + 6) login as the "user =" user with no password (guest connection) + 7) login as guest user with no password + + if the service is guest_only then steps 1 to 5 are skipped + */ + + if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { + /* check the given username and password */ + if (!ok && (*user) && user_ok(user,snum)) { + ok = password_ok(user,password, pwlen, NULL); + if (ok) + DEBUG(3,("authorise_login: ACCEPTED: given username (%s) password ok\n", + user )); + } - /* now check the list of session users */ - if (!ok) - { - char *auser; - char *user_list = strdup(session_users); - if (!user_list) return(False); + /* check for a previously registered guest username */ + if (!ok && (vuser != 0) && vuser->guest) { + if (user_ok(vuser->user.unix_name,snum) && + password_ok(vuser->user.unix_name, password, pwlen, NULL)) { + fstrcpy(user, vuser->user.unix_name); + vuser->guest = False; + DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user)); + ok = True; + } + } - for (auser=strtok(user_list,LIST_SEP); - !ok && auser; - auser = strtok(NULL,LIST_SEP)) - { - fstring user2; - fstrcpy(user2,auser); - if (!user_ok(user2,snum)) continue; + /* now check the list of session users */ + if (!ok) { + char *auser; + char *user_list = strdup(session_users); + if (!user_list) + return(False); + + for (auser=strtok(user_list,LIST_SEP); !ok && auser; + auser = strtok(NULL,LIST_SEP)) { + fstring user2; + fstrcpy(user2,auser); + if (!user_ok(user2,snum)) + continue; - if (password_ok(user2,password, pwlen, NULL)) { - ok = True; - fstrcpy(user,user2); - DEBUG(3,("ACCEPTED: session list username and given password ok\n")); - } - } - free(user_list); - } + if (password_ok(user2,password, pwlen, NULL)) { + ok = True; + fstrcpy(user,user2); + DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ +and given password ok\n", user)); + } + } - /* check for a previously validated username/password pair */ - if (!ok && (lp_security() > SEC_SHARE) && - (vuser != 0) && !vuser->guest && - user_ok(vuser->user.unix_name,snum)) { - fstrcpy(user,vuser->user.unix_name); - *guest = False; - DEBUG(3,("ACCEPTED: validated uid ok as non-guest\n")); - ok = True; - } + free(user_list); + } - /* check for a rhosts entry */ - if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { - ok = True; - DEBUG(3,("ACCEPTED: hosts equiv or rhosts entry\n")); - } + /* check for a previously validated username/password pair */ + if (!ok && (lp_security() > SEC_SHARE) && (vuser != 0) && !vuser->guest && + user_ok(vuser->user.unix_name,snum)) { + fstrcpy(user,vuser->user.unix_name); + *guest = False; + DEBUG(3,("authorise_login: ACCEPTED: validated uid (%s) as non-guest\n", + user)); + ok = True; + } - /* check the user= fields and the given password */ - if (!ok && lp_username(snum)) { - char *auser; - pstring user_list; - StrnCpy(user_list,lp_username(snum),sizeof(pstring)); + /* check for a rhosts entry */ + if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { + ok = True; + DEBUG(3,("authorise_login: ACCEPTED: hosts equiv or rhosts entry for %s\n", + user)); + } - pstring_sub(user_list,"%S",lp_servicename(snum)); - - for (auser=strtok(user_list,LIST_SEP); - auser && !ok; - auser = strtok(NULL,LIST_SEP)) - { - if (*auser == '@') - { - auser = validate_group(auser+1,password,pwlen,snum); - if (auser) - { - ok = True; - fstrcpy(user,auser); - DEBUG(3,("ACCEPTED: group username and given password ok\n")); - } - } - else - { - fstring user2; - fstrcpy(user2,auser); - if (user_ok(user2,snum) && - password_ok(user2,password,pwlen,NULL)) - { - ok = True; - fstrcpy(user,user2); - DEBUG(3,("ACCEPTED: user list username and given password ok\n")); - } - } - } - } - } /* not guest only */ + /* check the user= fields and the given password */ + if (!ok && lp_username(snum)) { + char *auser; + pstring user_list; + StrnCpy(user_list,lp_username(snum),sizeof(pstring)); - /* check for a normal guest connection */ - if (!ok && GUEST_OK(snum)) - { - fstring guestname; - StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); - if (Get_Pwnam(guestname,True)) - { - fstrcpy(user,guestname); - ok = True; - DEBUG(3,("ACCEPTED: guest account and guest ok\n")); + pstring_sub(user_list,"%S",lp_servicename(snum)); + + for (auser=strtok(user_list,LIST_SEP); auser && !ok; + auser = strtok(NULL,LIST_SEP)) { + if (*auser == '@') { + auser = validate_group(auser+1,password,pwlen,snum); + if (auser) { + ok = True; + fstrcpy(user,auser); + DEBUG(3,("authorise_login: ACCEPTED: group username \ +and given password ok (%s)\n", user)); + } + } else { + fstring user2; + fstrcpy(user2,auser); + if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL)) { + ok = True; + fstrcpy(user,user2); + DEBUG(3,("authorise_login: ACCEPTED: user list username \ +and given password ok (%s)\n", user)); + } + } + } + } + } /* not guest only */ + + /* check for a normal guest connection */ + if (!ok && GUEST_OK(snum)) { + fstring guestname; + StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); + if (Get_Pwnam(guestname,True)) { + fstrcpy(user,guestname); + ok = True; + DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n", + user)); + } else { + DEBUG(0,("authorise_login: Invalid guest account %s??\n",guestname)); + } + *guest = True; } - else - DEBUG(0,("Invalid guest account %s??\n",guestname)); - *guest = True; - } - if (ok && !user_ok(user,snum)) - { - DEBUG(0,("rejected invalid user %s\n",user)); - ok = False; - } + if (ok && !user_ok(user,snum)) { + DEBUG(0,("authorise_login: rejected invalid user %s\n",user)); + ok = False; + } - return(ok); + return(ok); } - /**************************************************************************** -read the a hosts.equiv or .rhosts file and check if it -allows this user from this machine + Read the a hosts.equiv or .rhosts file and check if it + allows this user from this machine. ****************************************************************************/ + static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) { int plus_allowed = 1; -- cgit From 31ab8ae3ffd5ac3f7af5f5d7157f568c0e6d199f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 25 Jun 2001 19:08:30 +0000 Subject: Fixed stupid typo that would stop trusted domains working. Jeremy. (This used to be commit fa721b4adfbcac4827251b02f6af7f0b5211c104) --- source3/smbd/password.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6be2989881..0c720b6a29 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1272,8 +1272,7 @@ use this machine as the password server.\n")); ************************************************************************/ static BOOL connect_to_domain_password_server(struct cli_state *pcli, - char *server, - unsigned char *trust_passwd) + char *server, unsigned char *trust_passwd) { struct in_addr dest_ip; fstring remote_machine; @@ -1573,9 +1572,9 @@ BOOL domain_client_validate( char *user, char *domain, /* * Get the machine account password for our primary domain */ - if (!secrets_fetch_trust_account_password(domain, trust_passwd, &last_change_time)) + if (!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd, &last_change_time)) { - DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", domain)); + DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", global_myworkgroup)); return False; } -- cgit From 87fbb7092b8f8b2f0db0f361c3d625e19de57cd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0c720b6a29..8bcd17d326 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -946,7 +946,7 @@ static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) int plus_allowed = 1; char *file_host; char *file_user; - char **lines = file_lines_load(equiv_file, NULL, False); + char **lines = file_lines_load(equiv_file, NULL); int i; DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); -- cgit From 5b8d230e39cedda6117cf8528065cbab45bdd835 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 8 Jul 2001 14:10:30 +0000 Subject: This removes unused paramaters from various authtication functions, and should not change behaviour. This should make my later diffs smaller, where I actualy start cleaning up this mess... Andrew Bartlett (This used to be commit 04f090c224bb7ac3b53c430a591fce1fc939a81c) --- source3/smbd/password.c | 35 ++++++++++++++--------------------- 1 file changed, 14 insertions(+), 21 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8bcd17d326..a0f730d7e2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -520,7 +520,7 @@ return True if the password is correct, False otherwise ****************************************************************************/ BOOL pass_check_smb(char *user, char *domain, uchar *chal, - uchar *lm_pwd, uchar *nt_pwd, struct passwd *pwd) + uchar *lm_pwd, uchar *nt_pwd) { struct passwd *pass; SAM_ACCOUNT *sampass=NULL; @@ -533,17 +533,10 @@ BOOL pass_check_smb(char *user, char *domain, uchar *chal, /* FIXME! this code looks to be unnecessary now that the passdb validates that the username exists and has a valid uid */ - if (pwd != NULL && user == NULL) - { - pass = (struct passwd *) pwd; - user = pass->pw_name; - } - else - { - /* I don't get this call here. I think it should be moved. - Need to check on it. --jerry */ - pass = smb_getpwnam(user,True); - } + + /* I don't get this call here. I think it should be moved. + Need to check on it. --jerry */ + pass = smb_getpwnam(user,True); if (pass == NULL) { @@ -612,7 +605,7 @@ check if a username/password pair is OK either via the system password database or the encrypted SMB password database return True if the password is correct, False otherwise ****************************************************************************/ -BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) +BOOL password_ok(char *user, char *password, int pwlen) { BOOL ret; @@ -631,7 +624,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) } ret = pass_check_smb(user, global_myworkgroup, - challenge, (uchar *)password, (uchar *)password, pwd); + challenge, (uchar *)password, (uchar *)password); /* * Try with PAM (may not be compiled in - returns True if not. JRA). @@ -643,7 +636,7 @@ BOOL password_ok(char *user, char *password, int pwlen, struct passwd *pwd) return (smb_pam_accountcheck(user) == NT_STATUS_NOPROBLEMO); } - return pass_check(user, password, pwlen, pwd, + return pass_check(user, password, pwlen, lp_update_encrypted() ? update_smbpassword_file : NULL); } @@ -692,7 +685,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && - password_ok(user,password,pwlen,NULL)) { + password_ok(user,password,pwlen)) { endnetgrent(); return(user); } @@ -747,7 +740,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) static fstring name; fstrcpy(name,member); if (user_ok(name,snum) && - password_ok(name,password,pwlen,NULL)) { + password_ok(name,password,pwlen)) { endgrent(); return(&name[0]); } @@ -822,7 +815,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { /* check the given username and password */ if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen, NULL); + ok = password_ok(user,password, pwlen); if (ok) DEBUG(3,("authorise_login: ACCEPTED: given username (%s) password ok\n", user )); @@ -831,7 +824,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->user.unix_name,snum) && - password_ok(vuser->user.unix_name, password, pwlen, NULL)) { + password_ok(vuser->user.unix_name, password, pwlen)) { fstrcpy(user, vuser->user.unix_name); vuser->guest = False; DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user)); @@ -853,7 +846,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen, NULL)) { + if (password_ok(user2,password, pwlen)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ @@ -902,7 +895,7 @@ and given password ok (%s)\n", user)); } else { fstring user2; fstrcpy(user2,auser); - if (user_ok(user2,snum) && password_ok(user2,password,pwlen,NULL)) { + if (user_ok(user2,snum) && password_ok(user2,password,pwlen)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: user list username \ -- cgit From e3fbb09cede1d2d8b5ad66c6952e86c153cfbefb Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 16 Jul 2001 12:16:48 +0000 Subject: Test if machine password has expired. This test was lost somehow... (This used to be commit 065d8f69d5f4a8ffc062bc5592386ee1ac652969) --- source3/smbd/password.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a0f730d7e2..e905d9207f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1571,6 +1571,12 @@ BOOL domain_client_validate( char *user, char *domain, return False; } + /* Test if machine password is expired and need to be changed */ + if (time(NULL) > last_change_time + lp_machine_password_timeout()) + { + global_machine_password_needs_changing = True; + } + /* * At this point, smb_apasswd points to the lanman response to * the challenge in local_challenge, and smb_ntpasswd points to -- cgit From 0cf44bb3476279e1db878b0793aa04b6bcc44a91 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 17 Jul 2001 08:34:12 +0000 Subject: move the global_machine_password_needs_changing where we need it. (This used to be commit 8a2f6fbacd275acc7b356169f4022df4860a813e) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e905d9207f..fb9c39bde4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -25,6 +25,8 @@ extern int DEBUGLEVEL; extern int Protocol; extern struct in_addr ipzero; +BOOL global_machine_password_needs_changing = False; + /* users from session setup */ static pstring session_users=""; -- cgit From 1cbae7315f99835ee294ce96858f73b5f8a18cfe Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Tue, 24 Jul 2001 20:02:48 +0000 Subject: Convert other parameters (read list, write list, valid users...) to the P_LIST format. changed functions to use list instead of strings addedd lp_list_substitute function (This used to be commit 7257d07563ba21bd88733d5d2b4ec4829fab2507) --- source3/smbd/password.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index fb9c39bde4..bc05d5f500 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -648,25 +648,34 @@ check if a username is valid ****************************************************************************/ BOOL user_ok(char *user,int snum) { - pstring valid, invalid; + char **valid, **invalid; BOOL ret; - StrnCpy(valid, lp_valid_users(snum), sizeof(pstring)-1); - StrnCpy(invalid, lp_invalid_users(snum), sizeof(pstring)-1); + valid = invalid = NULL; + ret = True; - pstring_sub(valid,"%S",lp_servicename(snum)); - pstring_sub(invalid,"%S",lp_servicename(snum)); - - ret = !user_in_list(user,invalid); - - if (ret && valid && *valid) { - ret = user_in_list(user,valid); + if (lp_invalid_users(snum)) { + lp_list_copy(&invalid, lp_invalid_users(snum)); + if (invalid && lp_list_substitute(invalid, "%S", lp_servicename(snum))) { + ret = !user_in_list(user, invalid); + } } + if (invalid) lp_list_free (&invalid); + + if (ret && lp_valid_users(snum)) { + lp_list_copy(&valid, lp_valid_users(snum)); + if (valid && lp_list_substitute(valid, "%S", lp_servicename(snum))) { + ret = user_in_list(user,valid); + } + } + if (valid) lp_list_free (&valid); if (ret && lp_onlyuser(snum)) { - char *user_list = lp_username(snum); - pstring_sub(user_list,"%S",lp_servicename(snum)); - ret = user_in_list(user,user_list); + char **user_list = lp_list_make (lp_username(snum)); + if (user_list && lp_list_substitute(user_list, "%S", lp_servicename(snum))) { + ret = user_in_list(user, user_list); + } + if (user_list) lp_list_free (&user_list); } return(ret); -- cgit From 61bb3093e32e9e1e58cec079ea101b5b11c5fee0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 1 Aug 2001 17:32:45 +0000 Subject: Pidfile check can be read-only. Removed old ifdef in password.c Jeremy. (This used to be commit d82efc61ef16533c5652a5d4a9863f8317cb4ea2) --- source3/smbd/password.c | 27 +++------------------------ 1 file changed, 3 insertions(+), 24 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index bc05d5f500..743d6ebffe 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -42,31 +42,10 @@ Get the next challenge value - no repeats. ********************************************************************/ void generate_next_challenge(char *challenge) { -#if 0 - /* - * Leave this ifdef'd out while we test - * the new crypto random number generator. - * JRA. - */ - unsigned char buf[16]; - static int counter = 0; - struct timeval tval; - int v1,v2; - - /* get a sort-of random number */ - GetTimeOfDay(&tval); - v1 = (counter++) + sys_getpid() + tval.tv_sec; - v2 = (counter++) * sys_getpid() + tval.tv_usec; - SIVAL(challenge,0,v1); - SIVAL(challenge,4,v2); - - /* mash it up with md4 */ - mdfour(buf, (unsigned char *)challenge, 8); -#else - unsigned char buf[8]; + unsigned char buf[8]; + + generate_random_buffer(buf,8,False); - generate_random_buffer(buf,8,False); -#endif memcpy(saved_challenge, buf, 8); memcpy(challenge,buf,8); challenge_sent = True; -- cgit From 986372901e85a79343ba32f590a4a3e7658d2565 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 3 Aug 2001 13:09:23 +0000 Subject: This is my 'Authentication Rewrite' version 1.01, mostly as submitted to samba-technical a few weeks ago. The idea here is to standardize the checking of user names and passwords, thereby ensuring that all authtentications pass the same standards. The interface currently implemented in as nt_status = check_password(user_info, server_info) where user_info contains (mostly) the authentication data, and server_info contains things like the user-id they got, and their resolved user name. The current ugliness with the way the structures are created will be killed the next revision, when they will be created and malloced by creator functions. This patch also includes the first implementation of NTLMv2 in HEAD, but which needs some more testing. We also add a hack to allow plaintext passwords to be compared with smbpasswd, not the system password database. Finally, this patch probably reintroduces the PAM accounts bug we had in 2.2.0, I'll fix that once this hits the tree. (I've just finished testing it on a wide variety of platforms, so I want to get this patch in). (This used to be commit b30b6202f31d339b48d51c0d38174cafd1cfcd42) --- source3/smbd/password.c | 1072 ----------------------------------------------- 1 file changed, 1072 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 743d6ebffe..4aa5a0211e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -25,52 +25,12 @@ extern int DEBUGLEVEL; extern int Protocol; extern struct in_addr ipzero; -BOOL global_machine_password_needs_changing = False; - /* users from session setup */ static pstring session_users=""; extern pstring global_myname; extern fstring global_myworkgroup; -/* Data to do lanman1/2 password challenge. */ -static unsigned char saved_challenge[8]; -static BOOL challenge_sent=False; - -/******************************************************************* -Get the next challenge value - no repeats. -********************************************************************/ -void generate_next_challenge(char *challenge) -{ - unsigned char buf[8]; - - generate_random_buffer(buf,8,False); - - memcpy(saved_challenge, buf, 8); - memcpy(challenge,buf,8); - challenge_sent = True; -} - -/******************************************************************* -set the last challenge sent, usually from a password server -********************************************************************/ -BOOL set_challenge(unsigned char *challenge) -{ - memcpy(saved_challenge,challenge,8); - challenge_sent = True; - return(True); -} - -/******************************************************************* -get the last challenge sent -********************************************************************/ -static BOOL last_challenge(unsigned char *challenge) -{ - if (!challenge_sent) return(False); - memcpy(challenge,saved_challenge,8); - return(True); -} - /* this holds info on user ids that are already validated for this VC */ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; @@ -341,287 +301,6 @@ void add_session_user(char *user) } -/**************************************************************************** -update the encrypted smbpasswd file from the plaintext username and password -*****************************************************************************/ -static BOOL update_smbpassword_file(char *user, char *password) -{ - SAM_ACCOUNT *sampass = NULL; - BOOL ret; - - pdb_init_sam(&sampass); - - become_root(); - ret = pdb_getsampwnam(sampass, user); - unbecome_root(); - - if(ret == False) { - DEBUG(0,("pdb_getsampwnam returned NULL\n")); - pdb_free_sam(sampass); - return False; - } - - /* - * Remove the account disabled flag - we are updating the - * users password from a login. - */ - pdb_set_acct_ctrl(sampass, pdb_get_acct_ctrl(sampass) & ~ACB_DISABLED); - - /* Here, the flag is one, because we want to ignore the - XXXXXXX'd out password */ - ret = change_oem_password( sampass, password, True); - if (ret == False) { - DEBUG(3,("change_oem_password returned False\n")); - } - - pdb_free_sam(sampass); - return ret; -} - -/**************************************************************************** -core of smb password checking routine. -****************************************************************************/ -BOOL smb_password_check(char *password, unsigned char *part_passwd, unsigned char *c8) -{ - /* Finish the encryption of part_passwd. */ - unsigned char p21[21]; - unsigned char p24[24]; - - if (part_passwd == NULL) - { - DEBUG(10,("No password set - allowing access\n")); - - /* No password set - always true ! */ - return 1; - } - - memset(p21,'\0',21); - memcpy(p21,part_passwd,16); - E_P24(p21, c8, p24); -#if DEBUG_PASSWORD - { - int i; - DEBUG(100,("Part password (P16) was |")); - for(i = 0; i < 16; i++) - DEBUG(100,("%X ", (unsigned char)part_passwd[i])); - DEBUG(100,("|\n")); - DEBUG(100,("Password from client was |")); - for(i = 0; i < 24; i++) - DEBUG(100,("%X ", (unsigned char)password[i])); - DEBUG(100,("|\n")); - DEBUG(100,("Given challenge was |")); - for(i = 0; i < 8; i++) - DEBUG(100,("%X ", (unsigned char)c8[i])); - DEBUG(100,("|\n")); - DEBUG(100,("Value from encryption was |")); - for(i = 0; i < 24; i++) - DEBUG(100,("%X ", (unsigned char)p24[i])); - DEBUG(100,("|\n")); - } -#endif - return (memcmp(p24, password, 24) == 0); -} - -/**************************************************************************** - Do a specific test for an smb password being correct, given a smb_password and - the lanman and NT responses. -****************************************************************************/ -BOOL smb_password_ok(SAM_ACCOUNT *sampass, uchar chal[8], - uchar lm_pass[24], uchar nt_pass[24]) -{ - uchar challenge[8]; - char* user_name; - uint8 *nt_pw, *lm_pw; - - if (!lm_pass || !sampass) - return(False); - - user_name = pdb_get_username(sampass); - - DEBUG(4,("smb_password_ok: Checking SMB password for user %s\n",user_name)); - - if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { - DEBUG(1,("smb_password_ok: account for user %s was disabled.\n", user_name)); - return(False); - } - - if (chal == NULL) { - DEBUG(5,("smb_password_ok: use last SMBnegprot challenge\n")); - if (!last_challenge(challenge)) { - DEBUG(1,("smb_password_ok: no challenge done - password failed\n")); - return False; - } - } else { - DEBUG(5,("smb_password_ok: challenge received\n")); - memcpy(challenge, chal, 8); - } - - nt_pw = pdb_get_nt_passwd(sampass); - - if ((Protocol >= PROTOCOL_NT1) && (nt_pw != NULL)) { - /* We have the NT MD4 hash challenge available - see if we can - use it (ie. does it exist in the smbpasswd file). - */ - DEBUG(4,("smb_password_ok: Checking NT MD4 password\n")); - if (smb_password_check((char *)nt_pass, (uchar *)nt_pw, challenge)) { - DEBUG(4,("smb_password_ok: NT MD4 password check succeeded\n")); - return(True); - } - DEBUG(4,("smb_password_ok: NT MD4 password check failed\n")); - } - - /* Try against the lanman password. pdb_get_lanman_passwd(sampass) == NULL - means no password, allow access. */ - - lm_pw = pdb_get_lanman_passwd(sampass); - - if((lm_pw == NULL) && (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ)) - { - DEBUG(4,("smb_password_ok: no password required for user %s\n",user_name)); - return True; - } - - if(lp_lanman_auth() && (lm_pw != NULL)) { - DEBUG(4,("smb_password_ok: Checking LM password\n")); - if(smb_password_check((char *)lm_pass,(uchar *)lm_pw, challenge)) { - DEBUG(4,("smb_password_ok: LM password check succeeded\n")); - return(True); - } - DEBUG(4,("smb_password_ok: LM password check failed\n")); - } - - return False; -} - - -/**************************************************************************** -check if a username/password is OK assuming the password is a 24 byte -SMB hash -return True if the password is correct, False otherwise -****************************************************************************/ - -BOOL pass_check_smb(char *user, char *domain, uchar *chal, - uchar *lm_pwd, uchar *nt_pwd) -{ - struct passwd *pass; - SAM_ACCOUNT *sampass=NULL; - BOOL ret; - - if (!lm_pwd || !nt_pwd) - { - return(False); - } - - /* FIXME! this code looks to be unnecessary now that the passdb - validates that the username exists and has a valid uid */ - - /* I don't get this call here. I think it should be moved. - Need to check on it. --jerry */ - pass = smb_getpwnam(user,True); - - if (pass == NULL) - { - DEBUG(1,("Couldn't find user '%s' in UNIX password database.\n",user)); - return(False); - } - - pdb_init_sam(&sampass); - - /* get the account information */ - ret = pdb_getsampwnam(sampass, user); - if (ret == False) - { - DEBUG(1,("Couldn't find user '%s' in passdb file.\n", user)); - pdb_free_sam(sampass); - return(False); - } - - /* Quit if the account was disabled. */ - if(pdb_get_acct_ctrl(sampass) & ACB_DISABLED) { - DEBUG(1,("Account for user '%s' was disabled.\n", user)); - pdb_free_sam(sampass); - return(False); - } - - /* Ensure the uid's match - FIXME! This also seems unnecessary --jerry */ -#if 0 /* GWC */ - if (smb_pass->smb_userid != pass->pw_uid) - { - DEBUG(0,("Error : UNIX and SMB uids in password files do not match for user '%s'!\n", user)); - pdb_free_sam(sampass); - return(False); - } -#endif - - if (pdb_get_acct_ctrl(sampass) & ACB_PWNOTREQ) - { - if (lp_null_passwords()) - { - DEBUG(3,("Account for user '%s' has no password and null passwords are allowed.\n", user)); - pdb_free_sam(sampass); - return(True); - } - else - { - DEBUG(3,("Account for user '%s' has no password and null passwords are NOT allowed.\n", user)); - pdb_free_sam(sampass); - return(False); - } - } - - if (smb_password_ok(sampass, chal, lm_pwd, nt_pwd)) - { - pdb_free_sam(sampass); - return(True); - } - - DEBUG(2,("pass_check_smb failed - invalid password for user [%s]\n", user)); - pdb_free_sam(sampass); - return False; -} - -/**************************************************************************** -check if a username/password pair is OK either via the system password -database or the encrypted SMB password database -return True if the password is correct, False otherwise -****************************************************************************/ -BOOL password_ok(char *user, char *password, int pwlen) -{ - BOOL ret; - - if ((pwlen == 0) && !lp_null_passwords()) { - DEBUG(4,("Null passwords not allowed.\n")); - return False; - } - - if (pwlen == 24 || (lp_encrypted_passwords() && (pwlen == 0) && lp_null_passwords())) { - /* if 24 bytes long assume it is an encrypted password */ - uchar challenge[8]; - - if (!last_challenge(challenge)) { - DEBUG(0,("Error: challenge not done for user=%s\n", user)); - return False; - } - - ret = pass_check_smb(user, global_myworkgroup, - challenge, (uchar *)password, (uchar *)password); - - /* - * Try with PAM (may not be compiled in - returns True if not. JRA). - * FIXME ! Should this be called if we're using winbindd ? What about - * non-local accounts ? JRA. - */ - - if (ret) - return (smb_pam_accountcheck(user) == NT_STATUS_NOPROBLEMO); - } - - return pass_check(user, password, pwlen, - lp_update_encrypted() ? - update_smbpassword_file : NULL); -} - /**************************************************************************** check if a username is valid ****************************************************************************/ @@ -660,9 +339,6 @@ BOOL user_ok(char *user,int snum) return(ret); } - - - /**************************************************************************** validate a group username entry. Return the username or NULL ****************************************************************************/ @@ -857,13 +533,6 @@ and given password ok\n", user)); ok = True; } - /* check for a rhosts entry */ - if (!ok && user_ok(user,snum) && check_hosts_equiv(user)) { - ok = True; - DEBUG(3,("authorise_login: ACCEPTED: hosts equiv or rhosts entry for %s\n", - user)); - } - /* check the user= fields and the given password */ if (!ok && lp_username(snum)) { char *auser; @@ -918,744 +587,3 @@ and given password ok (%s)\n", user)); return(ok); } - -/**************************************************************************** - Read the a hosts.equiv or .rhosts file and check if it - allows this user from this machine. -****************************************************************************/ - -static BOOL check_user_equiv(char *user, char *remote, char *equiv_file) -{ - int plus_allowed = 1; - char *file_host; - char *file_user; - char **lines = file_lines_load(equiv_file, NULL); - int i; - - DEBUG(5, ("check_user_equiv %s %s %s\n", user, remote, equiv_file)); - if (! lines) return False; - for (i=0; lines[i]; i++) { - char *buf = lines[i]; - trim_string(buf," "," "); - - if (buf[0] != '#' && buf[0] != '\n') - { - BOOL is_group = False; - int plus = 1; - char *bp = buf; - if (strcmp(buf, "NO_PLUS\n") == 0) - { - DEBUG(6, ("check_user_equiv NO_PLUS\n")); - plus_allowed = 0; - } - else { - if (buf[0] == '+') - { - bp++; - if (*bp == '\n' && plus_allowed) - { - /* a bare plus means everbody allowed */ - DEBUG(6, ("check_user_equiv everybody allowed\n")); - file_lines_free(lines); - return True; - } - } - else if (buf[0] == '-') - { - bp++; - plus = 0; - } - if (*bp == '@') - { - is_group = True; - bp++; - } - file_host = strtok(bp, " \t\n"); - file_user = strtok(NULL, " \t\n"); - DEBUG(7, ("check_user_equiv %s %s\n", file_host ? file_host : "(null)", - file_user ? file_user : "(null)" )); - if (file_host && *file_host) - { - BOOL host_ok = False; - -#if defined(HAVE_NETGROUP) && defined(HAVE_YP_GET_DEFAULT_DOMAIN) - if (is_group) - { - static char *mydomain = NULL; - if (!mydomain) - yp_get_default_domain(&mydomain); - if (mydomain && innetgr(file_host,remote,user,mydomain)) - host_ok = True; - } -#else - if (is_group) - { - DEBUG(1,("Netgroups not configured\n")); - continue; - } -#endif - - /* is it this host */ - /* the fact that remote has come from a call of gethostbyaddr - * means that it may have the fully qualified domain name - * so we could look up the file version to get it into - * a canonical form, but I would rather just type it - * in full in the equiv file - */ - if (!host_ok && !is_group && strequal(remote, file_host)) - host_ok = True; - - if (!host_ok) - continue; - - /* is it this user */ - if (file_user == 0 || strequal(user, file_user)) - { - DEBUG(5, ("check_user_equiv matched %s%s %s\n", - (plus ? "+" : "-"), file_host, - (file_user ? file_user : ""))); - file_lines_free(lines); - return (plus ? True : False); - } - } - } - } - } - file_lines_free(lines); - return False; -} - - -/**************************************************************************** -check for a possible hosts equiv or rhosts entry for the user -****************************************************************************/ -BOOL check_hosts_equiv(char *user) -{ - char *fname = NULL; - pstring rhostsfile; - struct passwd *pass = Get_Pwnam(user,True); - - if (!pass) - return(False); - - fname = lp_hosts_equiv(); - - /* note: don't allow hosts.equiv on root */ - if (fname && *fname && (pass->pw_uid != 0)) { - if (check_user_equiv(user,client_name(),fname)) - return(True); - } - - if (lp_use_rhosts()) - { - char *home = get_user_home_dir(user); - if (home) { - slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); - if (check_user_equiv(user,client_name(),rhostsfile)) - return(True); - } - } - - return(False); -} - - -/**************************************************************************** - Return the client state structure. -****************************************************************************/ - -struct cli_state *server_client(void) -{ - static struct cli_state pw_cli; - return &pw_cli; -} - -/**************************************************************************** - Support for server level security. -****************************************************************************/ - -struct cli_state *server_cryptkey(void) -{ - struct cli_state *cli; - fstring desthost; - struct in_addr dest_ip; - char *p, *pserver; - BOOL connected_ok = False; - - cli = server_client(); - - if (!cli_initialise(cli)) - return NULL; - - pserver = strdup(lp_passwordserver()); - p = pserver; - - while(next_token( &p, desthost, LIST_SEP, sizeof(desthost))) { - standard_sub_basic(desthost); - strupper(desthost); - - if(!resolve_name( desthost, &dest_ip, 0x20)) { - DEBUG(1,("server_cryptkey: Can't resolve address for %s\n",desthost)); - continue; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("Password server loop - disabling password server %s\n",desthost)); - continue; - } - - if (cli_connect(cli, desthost, &dest_ip)) { - DEBUG(3,("connected to password server %s\n",desthost)); - connected_ok = True; - break; - } - } - - free(pserver); - - if (!connected_ok) { - DEBUG(0,("password server not available\n")); - cli_shutdown(cli); - return NULL; - } - - if (!attempt_netbios_session_request(cli, global_myname, desthost, &dest_ip)) - return NULL; - - DEBUG(3,("got session\n")); - - if (!cli_negprot(cli)) { - DEBUG(1,("%s rejected the negprot\n",desthost)); - cli_shutdown(cli); - return NULL; - } - - if (cli->protocol < PROTOCOL_LANMAN2 || - !(cli->sec_mode & 1)) { - DEBUG(1,("%s isn't in user level security mode\n",desthost)); - cli_shutdown(cli); - return NULL; - } - - DEBUG(3,("password server OK\n")); - - return cli; -} - -/**************************************************************************** - Validate a password with the password server. -****************************************************************************/ - -BOOL server_validate(char *user, char *domain, - char *pass, int passlen, - char *ntpass, int ntpasslen) -{ - struct cli_state *cli; - static unsigned char badpass[24]; - static fstring baduser; - static BOOL tested_password_server = False; - static BOOL bad_password_server = False; - - cli = server_client(); - - if (!cli->initialised) { - DEBUG(1,("password server %s is not connected\n", cli->desthost)); - return(False); - } - - if(badpass[0] == 0) - memset(badpass, 0x1f, sizeof(badpass)); - - if((passlen == sizeof(badpass)) && !memcmp(badpass, pass, passlen)) { - /* - * Very unlikely, our random bad password is the same as the users - * password. - */ - memset(badpass, badpass[0]+1, sizeof(badpass)); - } - - if(baduser[0] == 0) { - fstrcpy(baduser, INVALID_USER_PREFIX); - fstrcat(baduser, global_myname); - } - - /* - * Attempt a session setup with a totally incorrect password. - * If this succeeds with the guest bit *NOT* set then the password - * server is broken and is not correctly setting the guest bit. We - * need to detect this as some versions of NT4.x are broken. JRA. - */ - - if(!tested_password_server) { - if (cli_session_setup(cli, baduser, (char *)badpass, sizeof(badpass), - (char *)badpass, sizeof(badpass), domain)) { - - /* - * We connected to the password server so we - * can say we've tested it. - */ - tested_password_server = True; - - if ((SVAL(cli->inbuf,smb_vwv2) & 1) == 0) { - DEBUG(0,("server_validate: password server %s allows users as non-guest \ -with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: This is broken (and insecure) behaviour. Please do not \ -use this machine as the password server.\n")); - cli_ulogoff(cli); - - /* - * Password server has the bug. - */ - bad_password_server = True; - return False; - } - cli_ulogoff(cli); - } - } else { - - /* - * We have already tested the password server. - * Fail immediately if it has the bug. - */ - - if(bad_password_server) { - DEBUG(0,("server_validate: [1] password server %s allows users as non-guest \ -with a bad password.\n", cli->desthost)); - DEBUG(0,("server_validate: [1] This is broken (and insecure) behaviour. Please do not \ -use this machine as the password server.\n")); - return False; - } - } - - /* - * Now we know the password server will correctly set the guest bit, or is - * not guest enabled, we can try with the real password. - */ - - if (!cli_session_setup(cli, user, pass, passlen, ntpass, ntpasslen, domain)) { - DEBUG(1,("password server %s rejected the password\n", cli->desthost)); - return False; - } - - /* if logged in as guest then reject */ - if ((SVAL(cli->inbuf,smb_vwv2) & 1) != 0) { - DEBUG(1,("password server %s gave us guest only\n", cli->desthost)); - cli_ulogoff(cli); - return(False); - } - - cli_ulogoff(cli); - - return(True); -} - -/*********************************************************************** - Connect to a remote machine for domain security authentication - given a name or IP address. -************************************************************************/ - -static BOOL connect_to_domain_password_server(struct cli_state *pcli, - char *server, unsigned char *trust_passwd) -{ - struct in_addr dest_ip; - fstring remote_machine; - - if(cli_initialise(pcli) == NULL) { - DEBUG(0,("connect_to_domain_password_server: unable to initialize client connection.\n")); - return False; - } - - if (is_ipaddress(server)) { - struct in_addr to_ip; - - /* we shouldn't have 255.255.255.255 forthe IP address of - a password server anyways */ - if ((to_ip.s_addr=inet_addr(server)) == 0xFFFFFFFF) { - DEBUG (0,("connect_to_domain_password_server: inet_addr(%s) returned 0xFFFFFFFF!\n", server)); - return False; - } - - if (!name_status_find(0x20, to_ip, remote_machine)) { - DEBUG(0, ("connect_to_domain_password_server: Can't " - "resolve name for IP %s\n", server)); - return False; - } - } else { - fstrcpy(remote_machine, server); - } - - standard_sub_basic(remote_machine); - strupper(remote_machine); - - if(!resolve_name( remote_machine, &dest_ip, 0x20)) { - DEBUG(1,("connect_to_domain_password_server: Can't resolve address for %s\n", remote_machine)); - cli_shutdown(pcli); - return False; - } - - if (ismyip(dest_ip)) { - DEBUG(1,("connect_to_domain_password_server: Password server loop - not using password server %s\n", - remote_machine)); - cli_shutdown(pcli); - return False; - } - - if (!cli_connect(pcli, remote_machine, &dest_ip)) { - DEBUG(0,("connect_to_domain_password_server: unable to connect to SMB server on \ -machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - if (!attempt_netbios_session_request(pcli, global_myname, remote_machine, &dest_ip)) { - DEBUG(0,("connect_to_password_server: machine %s rejected the NetBIOS \ -session request. Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - return False; - } - - pcli->protocol = PROTOCOL_NT1; - - if (!cli_negprot(pcli)) { - DEBUG(0,("connect_to_domain_password_server: machine %s rejected the negotiate protocol. \ -Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - if (pcli->protocol != PROTOCOL_NT1) { - DEBUG(0,("connect_to_domain_password_server: machine %s didn't negotiate NT protocol.\n", - remote_machine)); - cli_shutdown(pcli); - return False; - } - - /* - * Do an anonymous session setup. - */ - - if (!cli_session_setup(pcli, "", "", 0, "", 0, "")) { - DEBUG(0,("connect_to_domain_password_server: machine %s rejected the session setup. \ -Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - if (!(pcli->sec_mode & 1)) { - DEBUG(1,("connect_to_domain_password_server: machine %s isn't in user level security mode\n", - remote_machine)); - cli_shutdown(pcli); - return False; - } - - if (!cli_send_tconX(pcli, "IPC$", "IPC", "", 1)) { - DEBUG(0,("connect_to_domain_password_server: machine %s rejected the tconX on the IPC$ share. \ -Error was : %s.\n", remote_machine, cli_errstr(pcli) )); - cli_shutdown(pcli); - return False; - } - - /* - * We now have an anonymous connection to IPC$ on the domain password server. - */ - - /* - * Even if the connect succeeds we need to setup the netlogon - * pipe here. We do this as we may just have changed the domain - * account password on the PDC and yet we may be talking to - * a BDC that doesn't have this replicated yet. In this case - * a successful connect to a DC needs to take the netlogon connect - * into account also. This patch from "Bjart Kvarme" . - */ - - if(cli_nt_session_open(pcli, PIPE_NETLOGON) == False) { - DEBUG(0,("connect_to_domain_password_server: unable to open the domain client session to \ -machine %s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); - cli_nt_session_close(pcli); - cli_ulogoff(pcli); - cli_shutdown(pcli); - return False; - } - - if (cli_nt_setup_creds(pcli, trust_passwd) == False) { - DEBUG(0,("connect_to_domain_password_server: unable to setup the PDC credentials to machine \ -%s. Error was : %s.\n", remote_machine, cli_errstr(pcli))); - cli_nt_session_close(pcli); - cli_ulogoff(pcli); - cli_shutdown(pcli); - return(False); - } - - return True; -} - -/*********************************************************************** - Utility function to attempt a connection to an IP address of a DC. -************************************************************************/ - -static BOOL attempt_connect_to_dc(struct cli_state *pcli, struct in_addr *ip, unsigned char *trust_passwd) -{ - fstring dc_name; - - /* - * Ignore addresses we have already tried. - */ - - if (ip_equal(ipzero, *ip)) - return False; - - if (!lookup_pdc_name(global_myname, lp_workgroup(), ip, dc_name)) - return False; - - return connect_to_domain_password_server(pcli, dc_name, trust_passwd); -} - -/*********************************************************************** - We have been asked to dynamcially determine the IP addresses of - the PDC and BDC's for this DOMAIN, and query them in turn. -************************************************************************/ -static BOOL find_connect_pdc(struct cli_state *pcli, unsigned char *trust_passwd, time_t last_change_time) -{ - struct in_addr *ip_list = NULL; - int count = 0; - int i; - BOOL connected_ok = False; - time_t time_now = time(NULL); - BOOL use_pdc_only = False; - - /* - * If the time the machine password has changed - * was less than an hour ago then we need to contact - * the PDC only, as we cannot be sure domain replication - * has yet taken place. Bug found by Gerald (way to go - * Gerald !). JRA. - */ - - if (time_now - last_change_time < 3600) - use_pdc_only = True; - - if (!get_dc_list(use_pdc_only, lp_workgroup(), &ip_list, &count)) - return False; - - /* - * Firstly try and contact a PDC/BDC who has the same - * network address as any of our interfaces. - */ - for(i = 0; i < count; i++) { - if(!is_local_net(ip_list[i])) - continue; - - if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) - break; - - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Secondly try and contact a random PDC/BDC. - */ - if(!connected_ok) { - i = (sys_random() % count); - - if (!(connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) - ip_list[i] = ipzero; /* Tried and failed. */ - } - - /* - * Finally go through the IP list in turn, ignoring any addresses - * we have already tried. - */ - if(!connected_ok) { - /* - * Try and connect to any of the other IP addresses in the PDC/BDC list. - * Note that from a WINS server the #1 IP address is the PDC. - */ - for(i = 0; i < count; i++) { - if((connected_ok = attempt_connect_to_dc(pcli, &ip_list[i], trust_passwd))) - break; - } - } - - if(ip_list != NULL) - free((char *)ip_list); - - - return connected_ok; -} - -/*********************************************************************** - Do the same as security=server, but using NT Domain calls and a session - key from the machine password. If the server parameter is specified - use it, otherwise figure out a server from the 'password server' param. -************************************************************************/ - -BOOL domain_client_validate( char *user, char *domain, - char *smb_apasswd, int smb_apasslen, - char *smb_ntpasswd, int smb_ntpasslen, - BOOL *user_exists, char *server) -{ - unsigned char local_challenge[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - unsigned char trust_passwd[16]; - fstring remote_machine; - char *p, *pserver; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 info3; - struct cli_state cli; - uint32 smb_uid_low; - BOOL connected_ok = False; - time_t last_change_time; - - if(user_exists != NULL) - *user_exists = True; /* Only set false on a very specific error. */ - - /* - * Check that the requested domain is not our own machine name. - * If it is, we should never check the PDC here, we use our own local - * password file. - */ - - if(strequal( domain, global_myname)) { - DEBUG(3,("domain_client_validate: Requested domain was for this machine.\n")); - return False; - } - - /* - * Next, check that the passwords given were encrypted. - */ - - if(((smb_apasslen != 24) && (smb_apasslen != 0)) || - ((smb_ntpasslen != 24) && (smb_ntpasslen != 0))) { - - /* - * Not encrypted - do so. - */ - - DEBUG(5,("domain_client_validate: User passwords not in encrypted format.\n")); - generate_random_buffer( local_challenge, 8, False); - SMBencrypt( (uchar *)smb_apasswd, local_challenge, local_lm_response); - SMBNTencrypt((uchar *)smb_ntpasswd, local_challenge, local_nt_response); - smb_apasslen = 24; - smb_ntpasslen = 24; - smb_apasswd = (char *)local_lm_response; - smb_ntpasswd = (char *)local_nt_response; - } else { - - /* - * Encrypted - get the challenge we sent for these - * responses. - */ - - if (!last_challenge(local_challenge)) { - DEBUG(0,("domain_client_validate: no challenge done - password failed\n")); - return False; - } - } - - /* - * Get the machine account password for our primary domain - */ - if (!secrets_fetch_trust_account_password(global_myworkgroup, trust_passwd, &last_change_time)) - { - DEBUG(0, ("domain_client_validate: could not fetch trust account password for domain %s\n", global_myworkgroup)); - return False; - } - - /* Test if machine password is expired and need to be changed */ - if (time(NULL) > last_change_time + lp_machine_password_timeout()) - { - global_machine_password_needs_changing = True; - } - - /* - * At this point, smb_apasswd points to the lanman response to - * the challenge in local_challenge, and smb_ntpasswd points to - * the NT response to the challenge in local_challenge. Ship - * these over the secure channel to a domain controller and - * see if they were valid. - */ - - ZERO_STRUCT(cli); - - /* - * Treat each name in the 'password server =' line as a potential - * PDC/BDC. Contact each in turn and try and authenticate. - */ - - if (server) { - p = server; - } else { - pserver = lp_passwordserver(); - if (! *pserver) pserver = "*"; - p = pserver; - } - - while (!connected_ok && - next_token(&p,remote_machine,LIST_SEP,sizeof(remote_machine))) { - if(strequal(remote_machine, "*")) { - connected_ok = find_connect_pdc(&cli, trust_passwd, last_change_time); - } else { - connected_ok = connect_to_domain_password_server(&cli, remote_machine, trust_passwd); - } - } - - if (!connected_ok) { - DEBUG(0,("domain_client_validate: Domain password server not available.\n")); - cli_shutdown(&cli); - return False; - } - - /* We really don't care what LUID we give the user. */ - generate_random_buffer( (unsigned char *)&smb_uid_low, 4, False); - - ZERO_STRUCT(info3); - - if(cli_nt_login_network(&cli, domain, user, smb_uid_low, (char *)local_challenge, - ((smb_apasslen != 0) ? smb_apasswd : NULL), - ((smb_ntpasslen != 0) ? smb_ntpasswd : NULL), - &ctr, &info3) == False) { - uint32 nt_rpc_err; - - cli_error(&cli, NULL, NULL, &nt_rpc_err); - DEBUG(0,("domain_client_validate: unable to validate password for user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); - cli_nt_session_close(&cli); - cli_ulogoff(&cli); - cli_shutdown(&cli); - - if((nt_rpc_err == NT_STATUS_NO_SUCH_USER) && (user_exists != NULL)) - *user_exists = False; - - return False; - } - - /* - * Here, if we really want it, we have lots of info about the user in info3. - */ - -#if 0 - /* - * We don't actually need to do this - plus it fails currently with - * NT_STATUS_INVALID_INFO_CLASS - we need to know *exactly* what to - * send here. JRA. - */ - - if(cli_nt_logoff(&cli, &ctr) == False) { - DEBUG(0,("domain_client_validate: unable to log off user %s in domain \ -%s to Domain controller %s. Error was %s.\n", user, domain, remote_machine, cli_errstr(&cli))); - cli_nt_session_close(&cli); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return False; - } -#endif /* 0 */ - - /* Note - once the cli stream is shutdown the mem_ctx used - to allocate the other_sids and gids structures has been deleted - so - these pointers are no longer valid..... */ - - cli_nt_session_close(&cli); - cli_ulogoff(&cli); - cli_shutdown(&cli); - return True; -} -- cgit From 90d2460cf0e644e82650763c502332e5adad27e7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Aug 2001 05:38:44 +0000 Subject: One less getpwnam() call... Andrew Bartlett (This used to be commit 204da7ba96b0c562bab5e5536728a0378077bdc7) --- source3/smbd/password.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4aa5a0211e..b4d22a3850 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -203,10 +203,9 @@ tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest) + char *domain,BOOL guest, char* full_name) { user_struct *vuser = NULL; - struct passwd *pwfile; /* for getting real name from passwd file */ /* Ensure no vuid gets registered in share level security. */ if(lp_security() == SEC_SHARE) @@ -243,6 +242,8 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, fstrcpy(vuser->user.unix_name,unix_name); fstrcpy(vuser->user.smb_name,requested_name); fstrcpy(vuser->user.domain,domain); + fstrcpy(vuser->user.full_name, full_name); + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name)); vuser->n_groups = 0; vuser->groups = NULL; @@ -260,14 +261,6 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DLIST_ADD(validated_users, vuser); - DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); - - DEBUG(3, ("Clearing default real name\n")); - if ((pwfile=sys_getpwnam(vuser->user.unix_name))!= NULL) { - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,pwfile->pw_gecos)); - fstrcpy(vuser->user.full_name, pwfile->pw_gecos); - } - if (!session_claim(vuser->vuid)) { DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid)); invalidate_vuid(vuser->vuid); -- cgit From a0171765ff080ea0510f8c4475348e6b33044b9b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Aug 2001 06:06:56 +0000 Subject: Style cleanup for the last vuid change. Style, doco and DEBUG() fixes for auth_smbpasswd.c (In particular for the account control call). Andrew Bartlett (This used to be commit 3d91c119420973d7dd1af416a1e26efa113dc626) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b4d22a3850..bbdd0c3bf5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -203,7 +203,7 @@ tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest, char* full_name) + char *domain,BOOL guest, char *full_name) { user_struct *vuser = NULL; -- cgit From 578a39d44f532a211169a7635043e2dfc18b3c65 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Aug 2001 07:03:27 +0000 Subject: smbd/auth_server: Doco, we want to use cli_nt_error here soon smbd/password.c: We don't use globals here anymore smbd/reply.c: Tidyness, global_myworkgroup must die! smbd/service.c: Move some of the make_connection code into a helper function. (This used to be commit 15c87e404fcaff9e360a40b8b673938c6e611daf) --- source3/smbd/password.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index bbdd0c3bf5..51df7a95a2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -28,9 +28,6 @@ extern struct in_addr ipzero; /* users from session setup */ static pstring session_users=""; -extern pstring global_myname; -extern fstring global_myworkgroup; - /* this holds info on user ids that are already validated for this VC */ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; -- cgit From 7c332851b0ac4eab77f6e449cefd48f119c7ddf6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 17 Aug 2001 07:47:10 +0000 Subject: Restore a debug I think I dropped earlier (This used to be commit dc635bde2262b248f58d3ce52c2575dae8546571) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 51df7a95a2..036cdbc55b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -253,6 +253,8 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Create an NT_USER_TOKEN struct for this user. */ vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups, guest); + DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); + next_vuid++; num_validated_vuids++; -- cgit From 11ce0f4d2d493702386c0bd49c8e2dd2aad84d56 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Aug 2001 05:15:26 +0000 Subject: a bunch of fixes from the sflight to seattle in particular: - fixed NT status code for a bunch of ops - fixed handling of protocol levels in ms_fnmatch (This used to be commit 3eba9606f71f90bfd9820af26f8676277ed22390) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 036cdbc55b..8e85ef3389 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -22,7 +22,6 @@ #include "includes.h" extern int DEBUGLEVEL; -extern int Protocol; extern struct in_addr ipzero; /* users from session setup */ -- cgit From 7892c494e7321c64b20bf7e1d794a6b6508fe84a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Sep 2001 12:55:59 +0000 Subject: Kill off the //server/share%user hack in share level security. This should help make much of this code simpiler. Andrew Bartlett (This used to be commit fb0c3629c360fd0c57129500474960e6da6f9ef0) --- source3/smbd/password.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8e85ef3389..13a54cb704 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -470,14 +470,6 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, */ if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { - /* check the given username and password */ - if (!ok && (*user) && user_ok(user,snum)) { - ok = password_ok(user,password, pwlen); - if (ok) - DEBUG(3,("authorise_login: ACCEPTED: given username (%s) password ok\n", - user )); - } - /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->user.unix_name,snum) && -- cgit From 61b2794968faa35dc91edce17e9b91e5366c3514 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 11:25:41 +0000 Subject: move to SAFE_FREE() (This used to be commit a95943fde0ad89ae3f2deca2f7ba9cb5ab612b74) --- source3/smbd/password.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 13a54cb704..a05735b4d7 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -71,9 +71,9 @@ void invalidate_vuid(uint16 vuid) DLIST_REMOVE(validated_users, vuser); - safe_free(vuser->groups); + SAFE_FREE(vuser->groups); delete_nt_token(&vuser->nt_user_token); - safe_free(vuser); + SAFE_FREE(vuser); num_validated_vuids--; } @@ -139,7 +139,7 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, num_sids = 5 + ngroups; if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { - free(token); + SAFE_FREE(token); return NULL; } @@ -503,7 +503,7 @@ and given password ok\n", user)); } } - free(user_list); + SAFE_FREE(user_list); } /* check for a previously validated username/password pair */ -- cgit From 60d315cb725ea3dfab010808c4ff4181f1f30255 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 30 Sep 2001 04:28:43 +0000 Subject: Small changes to register_vuid ahead of a larger restructure. (This used to be commit 7802bc94e78932d24eb6658edc14d0d051246208) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a05735b4d7..6f5c7508a4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -246,13 +246,13 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, /* Find all the groups this uid is in and store them. Used by become_user() */ - initialise_groups(unix_name, uid, gid); + initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); get_current_groups( &vuser->n_groups, &vuser->groups); /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(uid,gid, vuser->n_groups, vuser->groups, guest); + vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest); - DEBUG(3,("uid %d registered to name %s\n",(int)uid,unix_name)); + DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name)); next_vuid++; num_validated_vuids++; -- cgit From dc1fc3ee8ec2199bc73bb5d7ec711c6800f61d65 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 2 Oct 2001 04:29:50 +0000 Subject: Removed 'extern int DEBUGLEVEL' as it is now in the smb.h header. (This used to be commit 2d0922b0eabfdc0aaf1d0797482fef47ed7fde8e) --- source3/smbd/password.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6f5c7508a4..b074552567 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,6 @@ #include "includes.h" -extern int DEBUGLEVEL; extern struct in_addr ipzero; /* users from session setup */ -- cgit From c416ff851b4ecc7a44aee9d00d07dd481d8ae2a7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2001 20:15:12 +0000 Subject: Merge the become_XXX -> change_to_XXX fixes from 2.2.2 to HEAD. Ensure make_conection() can only be called as root. Jeremy. (This used to be commit 8d23a7441b4687458ee021bfe8880558506eddba) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b074552567..b1739d9bb6 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -244,7 +244,7 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, vuser->groups = NULL; /* Find all the groups this uid is in and store them. - Used by become_user() */ + Used by change_to_user() */ initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); get_current_groups( &vuser->n_groups, &vuser->groups); -- cgit From 2038649e51f48a489aeec49947e1b791f0b3df43 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Oct 2001 07:28:32 +0000 Subject: This commit is number 3 of 4. In particular this commit focuses on: Changing the Get_Pwnam code so that it can work in a const-enforced environment. While these changes have been mildly tested, and are pretty small, any assistance in this is appreciated. ---- These changes allow for 'const' in the Samba tree. There are a number of good reasons to do this: - I want to allow the SAM_ACCOUNT structure to move from wasteful pstrings and fstrings to allocated strings. We can't do that if people are modifying these outputs, as they may well make assumptions about getting pstrings and fstrings - I want --with-pam_smbpass to compile with a slightly sane volume of warnings, currently its pretty bad, even in 2.2 where is compiles at all. - Tridge assures me that he no longer opposes 'const religion' based on the ability to #define const the problem away. - Changed Get_Pwnam(x,y) into two variants (so that the const parameter can work correctly): - Get_Pwnam(const x) and Get_Pwnam_Modify(x). - Reworked smbd/chgpasswd.c to work with these mods, passing around a 'struct passwd' rather than the modified username (This used to be commit e7634f81c5116ff4addfb7e495f54b6bb78e8f77) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b1739d9bb6..e8f40f1fa3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -276,7 +276,7 @@ void add_session_user(char *user) fstring suser; StrnCpy(suser,user,sizeof(suser)-1); - if (!Get_Pwnam(suser,True)) return; + if (!Get_Pwnam_Modify(suser)) return; if (suser && *suser && !in_list(suser,session_users,False)) { @@ -551,7 +551,7 @@ and given password ok (%s)\n", user)); if (!ok && GUEST_OK(snum)) { fstring guestname; StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); - if (Get_Pwnam(guestname,True)) { + if (Get_Pwnam(guestname)) { fstrcpy(user,guestname); ok = True; DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n", -- cgit From 60f0627afb167faad57385d44f0b587186a7ac2b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 31 Oct 2001 10:46:25 +0000 Subject: This is a farily large patch (3300 lines) and reworks most of the AuthRewrite code. In particular this assists tpot in some of his work, becouse it provides the connection between the authenticaion and the vuid generation. Major Changes: - Fully malloc'ed structures. - Massive rework of the code so that all structures are made and destroyed using malloc and free, rather than hanging around on the stack. - SAM_ACCOUNT unix uids and gids are now pointers to the same, to allow them to be declared 'invalid' without the chance that people might get ROOT by default. - kill off some of the "DOMAIN\user" lookups. These can be readded at a more appropriate place (probably domain_client_validate.c) in the future. They don't belong in session setups. - Massive introduction of DATA_BLOB structures, particularly for passwords. - Use NTLMSSP flags to tell the backend what its getting, rather than magic lenghths. - Fix winbind back up again, but tpot is redoing this soon anyway. - Abstract much of the work in srv_netlog_nt back into auth helper functions. This is a LARGE change, and any assistance is testing it is appriciated. Domain logons are still broken (as far as I can tell) but other functionality seems intact. Needs testing with a wide variety of MS clients. Andrew Bartlett (This used to be commit f70fb819b2f57bd57232b51808345e2319d52f6c) --- source3/smbd/password.c | 51 +++++++++++++++++++++++++++++++------------------ 1 file changed, 32 insertions(+), 19 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e8f40f1fa3..01eabfda5e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -197,10 +197,11 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, - char *domain,BOOL guest, char *full_name) +int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL guest) { user_struct *vuser = NULL; + uid_t *puid; + gid_t *pgid; /* Ensure no vuid gets registered in share level security. */ if(lp_security() == SEC_SHARE) @@ -217,8 +218,14 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, ZERO_STRUCTP(vuser); - DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)uid, (unsigned int)gid, - unix_name, requested_name, domain, guest )); + puid = pdb_get_uid(server_info->sam_account); + pgid = pdb_get_gid(server_info->sam_account); + + if (!puid || !pgid) { + DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); + free(vuser); + return UID_FIELD_INVALID; + } /* Allocate a free vuid. Yes this is a linear search... :-) */ while( get_valid_user_struct(next_vuid) != NULL ) { @@ -231,13 +238,19 @@ int register_vuid(uid_t uid,gid_t gid, char *unix_name, char *requested_name, DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid )); vuser->vuid = next_vuid; - vuser->uid = uid; - vuser->gid = gid; + vuser->uid = *puid; + vuser->gid = *pgid; vuser->guest = guest; - fstrcpy(vuser->user.unix_name,unix_name); - fstrcpy(vuser->user.smb_name,requested_name); - fstrcpy(vuser->user.domain,domain); - fstrcpy(vuser->user.full_name, full_name); + fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); + fstrcpy(vuser->user.smb_name, smb_name); + fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); + fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); + + DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", + (unsigned int)vuser->uid, + (unsigned int)vuser->gid, + vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, guest )); + DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name)); vuser->n_groups = 0; @@ -332,7 +345,7 @@ BOOL user_ok(char *user,int snum) /**************************************************************************** validate a group username entry. Return the username or NULL ****************************************************************************/ -static char *validate_group(char *group,char *password,int pwlen,int snum) +static char *validate_group(char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP { @@ -341,7 +354,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) while (getnetgrent(&host, &user, &domain)) { if (user) { if (user_ok(user, snum) && - password_ok(user,password,pwlen)) { + password_ok(user,password)) { endnetgrent(); return(user); } @@ -396,7 +409,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) static fstring name; fstrcpy(name,member); if (user_ok(name,snum) && - password_ok(name,password,pwlen)) { + password_ok(name,password)) { endgrent(); return(&name[0]); } @@ -419,7 +432,7 @@ static char *validate_group(char *group,char *password,int pwlen,int snum) Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ -BOOL authorise_login(int snum,char *user,char *password, int pwlen, +BOOL authorise_login(int snum,char *user, DATA_BLOB password, BOOL *guest,BOOL *force,uint16 vuid) { BOOL ok = False; @@ -427,7 +440,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, #if DEBUG_PASSWORD DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", - user,password)); + user,password.data)); #endif *guest = False; @@ -472,7 +485,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, /* check for a previously registered guest username */ if (!ok && (vuser != 0) && vuser->guest) { if (user_ok(vuser->user.unix_name,snum) && - password_ok(vuser->user.unix_name, password, pwlen)) { + password_ok(vuser->user.unix_name, password)) { fstrcpy(user, vuser->user.unix_name); vuser->guest = False; DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user)); @@ -494,7 +507,7 @@ BOOL authorise_login(int snum,char *user,char *password, int pwlen, if (!user_ok(user2,snum)) continue; - if (password_ok(user2,password, pwlen)) { + if (password_ok(user2,password)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ @@ -526,7 +539,7 @@ and given password ok\n", user)); for (auser=strtok(user_list,LIST_SEP); auser && !ok; auser = strtok(NULL,LIST_SEP)) { if (*auser == '@') { - auser = validate_group(auser+1,password,pwlen,snum); + auser = validate_group(auser+1,password,snum); if (auser) { ok = True; fstrcpy(user,auser); @@ -536,7 +549,7 @@ and given password ok (%s)\n", user)); } else { fstring user2; fstrcpy(user2,auser); - if (user_ok(user2,snum) && password_ok(user2,password,pwlen)) { + if (user_ok(user2,snum) && password_ok(user2,password)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: user list username \ -- cgit From f8e2baf39eb864481dd48f61404136b325cd73c2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 3 Nov 2001 23:34:24 +0000 Subject: Added NT_USER_TOKEN into server_info to fix extra groups problem. Got "medieval on our ass" about const warnings (as many as I could :-). Jeremy. (This used to be commit ee5e7ca547eff016818ba5c43b8ea0c9fa69b808) --- source3/smbd/password.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 01eabfda5e..429d72b4e5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -117,7 +117,7 @@ char *validated_domain(uint16 vuid) Create the SID list for this user. ****************************************************************************/ -NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest) +NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok) { extern DOM_SID global_sid_World; extern DOM_SID global_sid_Network; @@ -137,6 +137,9 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */ num_sids = 5 + ngroups; + if (sup_tok && sup_tok->num_sids) + num_sids += sup_tok->num_sids; + if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { SAFE_FREE(token); return NULL; @@ -149,13 +152,15 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, * se_access_check depends on this. */ - uid_to_sid( &psids[psid_ndx++], uid); + uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid); + psid_ndx++; /* * Primary group SID is second in token. Convention. */ - gid_to_sid( &psids[psid_ndx++], gid); + gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid); + psid_ndx++; /* Now add the group SIDs. */ @@ -165,6 +170,10 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, } } + /* Now add the additional SIDs from the supplimentary token. */ + for (i = 0; i < sup_tok->num_sids; i++) + sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); + /* * Finally add the "standard" SIDs. * The only difference between guest and "anonymous" (which we @@ -218,8 +227,8 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu ZERO_STRUCTP(vuser); - puid = pdb_get_uid(server_info->sam_account); - pgid = pdb_get_gid(server_info->sam_account); + puid = pdb_get_uid(server_info->sam_account); + pgid = pdb_get_gid(server_info->sam_account); if (!puid || !pgid) { DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); @@ -261,8 +270,11 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); get_current_groups( &vuser->n_groups, &vuser->groups); + if (server_info->ptok) + add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); + /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest); + vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest, server_info->ptok); DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name)); -- cgit From c42bdbdacec8f9d4fe14ffba6e14778b691a6ff2 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 4 Nov 2001 04:58:17 +0000 Subject: Fix segfault. sup_tok might not always be with us. (This used to be commit 1f409a1f3fb0906f1ff985b96bb7a65f56253046) --- source3/smbd/password.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 429d72b4e5..f0fec9b796 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -170,9 +170,11 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, } } - /* Now add the additional SIDs from the supplimentary token. */ - for (i = 0; i < sup_tok->num_sids; i++) - sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); + if (sup_tok) { + /* Now add the additional SIDs from the supplimentary token. */ + for (i = 0; i < sup_tok->num_sids; i++) + sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); + } /* * Finally add the "standard" SIDs. -- cgit From 55dfb66079333acd8e0aee91c0ee90d0a413a8e6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Nov 2001 22:19:01 +0000 Subject: Change to guest logon code. This changes the way we process guest logons - we now treat them as normal logons, but set the 'guest' flag. In particular this is needed becouse Win2k will do an NTLMSSP login with username "", therefore missing our previous guest connection code - this is getting a pain to do as a special case all over the shop. Tridge: We don't seem to be setting a guest bit for NTLMSSP, in either the anonymous or authenticated case, can you take a look at this? Also some cleanups in the check_password() code that should make some of the debugs clearer. Various other minor cleanups: - change the session code to just take a vuser, rather than having to do a vuid lookup on vuser.vuid - Change some of the global_client_caps linking - Better debug in authorise_login(): show the vuid. Andrew Bartlett (This used to be commit 62f4e4bd0aef9ade653b3f8d575d2864c166ab4d) --- source3/smbd/password.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f0fec9b796..cbd4d14681 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -66,7 +66,7 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; - session_yield(vuid); + session_yield(vuser); DLIST_REMOVE(validated_users, vuser); @@ -208,7 +208,7 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL guest) +int register_vuid(auth_serversupplied_info *server_info, char *smb_name) { user_struct *vuser = NULL; uid_t *puid; @@ -251,7 +251,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu vuser->vuid = next_vuid; vuser->uid = *puid; vuser->gid = *pgid; - vuser->guest = guest; + vuser->guest = server_info->guest; fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); fstrcpy(vuser->user.smb_name, smb_name); fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); @@ -260,7 +260,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, (unsigned int)vuser->gid, - vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, guest )); + vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, vuser->guest )); DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name)); @@ -276,7 +276,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, guest, server_info->ptok); + vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, vuser->guest, server_info->ptok); DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name)); @@ -285,7 +285,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name, BOOL gu DLIST_ADD(validated_users, vuser); - if (!session_claim(vuser->vuid)) { + if (!session_claim(vuser)) { DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid)); invalidate_vuid(vuser->vuid); return -1; @@ -453,8 +453,8 @@ BOOL authorise_login(int snum,char *user, DATA_BLOB password, user_struct *vuser = get_valid_user_struct(vuid); #if DEBUG_PASSWORD - DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", - user,password.data)); + DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s vuid=%d\n", + user,password.data, vuid)); #endif *guest = False; @@ -501,7 +501,7 @@ BOOL authorise_login(int snum,char *user, DATA_BLOB password, if (user_ok(vuser->user.unix_name,snum) && password_ok(vuser->user.unix_name, password)) { fstrcpy(user, vuser->user.unix_name); - vuser->guest = False; + *guest = False; DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user)); ok = True; } -- cgit From 395aa946cd4fb9d5e07dd2fee418045a8064dfab Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 9 Nov 2001 11:16:06 +0000 Subject: This change updates lp_guestaccount() to be a *global* paramater, rather than per-share. I beleive that almost all the things that this could have done on a per-share basis can be done with other tools, like 'force user'. Almost all the user's of this paramater used it as a global anyway... While this is one step at a time, I hope it will allow me to considerably simplfy the make_connection() code, particularly for the user-level security case. This already removes an absolute truckload of extra attempted password lookups on the guest account. Andrew Bartlett (This used to be commit 8e708332eded210c1d1fe0cebca3c9c19f054b71) --- source3/smbd/password.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index cbd4d14681..b2687980ac 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -474,11 +474,12 @@ BOOL authorise_login(int snum,char *user, DATA_BLOB password, return False; } - if (!vuser->guest && user_ok(vuser->user.unix_name,snum)) { + if ((!vuser->guest && user_ok(vuser->user.unix_name,snum)) || + (vuser->guest && GUEST_OK(snum))) { fstrcpy(user,vuser->user.unix_name); - *guest = False; - DEBUG(3,("authorise_login: ACCEPTED: validated uid ok as non-guest \ -(user=%s)\n", user)); + *guest = vuser->guest; + DEBUG(3,("authorise_login: ACCEPTED: validated based on vuid as %sguest \ +(user=%s)\n", vuser->guest ? "" : "non-", user)); return True; } } @@ -577,7 +578,7 @@ and given password ok (%s)\n", user)); /* check for a normal guest connection */ if (!ok && GUEST_OK(snum)) { fstring guestname; - StrnCpy(guestname,lp_guestaccount(snum),sizeof(guestname)-1); + StrnCpy(guestname,lp_guestaccount(),sizeof(guestname)-1); if (Get_Pwnam(guestname)) { fstrcpy(user,guestname); ok = True; -- cgit From 0085229b2a2da40867863792230c179b9287336b Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 19 Nov 2001 04:35:00 +0000 Subject: Cosmetic fix for debug statement. (This used to be commit 507ef80f48a8fca762e41be5cdb80ce86544da3f) --- source3/smbd/password.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b2687980ac..510e18919d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -469,8 +469,7 @@ BOOL authorise_login(int snum,char *user, DATA_BLOB password, */ if (!vuser) { - DEBUG(1,("authorise_login: refusing user %s with no session setup\n", - user)); + DEBUG(1,("authorise_login: refusing user '%s' with no session setup\n", user)); return False; } -- cgit From 585d0efbc6428e5876d354fee49c241c1bad809d Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 26 Nov 2001 03:11:44 +0000 Subject: Got medieval on another pointless extern. Removed extern struct ipzero and replaced with two functions: void zero_ip(struct in_adder *ip); BOOL is_zero_ip(struct in_addr ip); (This used to be commit 778f5f77a66cda76348a7c6f64cd63afe2bfe077) --- source3/smbd/password.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 510e18919d..71837efdcb 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,8 +21,6 @@ #include "includes.h" -extern struct in_addr ipzero; - /* users from session setup */ static pstring session_users=""; -- cgit From 04aff47c716a51a1039b44a81d6ff19eeaa09017 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 27 Dec 2001 06:38:04 +0000 Subject: moving SAM_ACCOUNT to include a bit field for initialized members (such as uid and gid). This way we will be able to keep ourselves from writing out default smb.conf settings when the admin doesn't want to, That part is not done yet. Tested compiles with ldap/tdb/smbpasswd. Tested connection with smbpasswd backend. oh...and smbpasswd doesn'y automatically expire accounts after 21 days from the last password change either now. Just ifdef'd out that code in build_sam_account(). Will merge updates into 2.2 as they are necessary. jerry (This used to be commit f0d43791157d8f04a13a07d029f203ad4384d317) --- source3/smbd/password.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 71837efdcb..538225e245 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -209,8 +209,8 @@ tell random client vuid's (normally zero) from valid vuids. int register_vuid(auth_serversupplied_info *server_info, char *smb_name) { user_struct *vuser = NULL; - uid_t *puid; - gid_t *pgid; + uid_t uid; + gid_t gid; /* Ensure no vuid gets registered in share level security. */ if(lp_security() == SEC_SHARE) @@ -227,15 +227,15 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) ZERO_STRUCTP(vuser); - puid = pdb_get_uid(server_info->sam_account); - pgid = pdb_get_gid(server_info->sam_account); - - if (!puid || !pgid) { + if (!IS_SAM_UNIX_USER(server_info->sam_account)) { DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); free(vuser); return UID_FIELD_INVALID; } + uid = pdb_get_uid(server_info->sam_account); + gid = pdb_get_gid(server_info->sam_account); + /* Allocate a free vuid. Yes this is a linear search... :-) */ while( get_valid_user_struct(next_vuid) != NULL ) { next_vuid++; @@ -247,8 +247,8 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid )); vuser->vuid = next_vuid; - vuser->uid = *puid; - vuser->gid = *pgid; + vuser->uid = uid; + vuser->gid = gid; vuser->guest = server_info->guest; fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); fstrcpy(vuser->user.smb_name, smb_name); -- cgit From a3f891dbd2e9ee1681e3c8295cd62a877c727d4f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Jan 2002 07:41:54 +0000 Subject: Actually enforce the passdb API. Thou shalt not reference SAM_ACCOUNT members directly - always use pdb_get/pdb_set. This is achived by making the whole of SAM_ACCOUNT have a .private member, where the real members live. This caught a pile of examples, and these have beeen fixed. The pdb_get..() functions are 'const' (have been for some time) and this required a few small changes to constify other functions. I've also added some debugs to the pdb get and set, they can be removed if requested. I've rewritten the copy_id2x_to_sam_pass() functions to use the new passdb interface, but I need the flags info to do it properly. The pdb_free_sam() funciton now blanks out the LM and NT hashes, and as such I have removed many extra 'samr_clear_sam_passwd(smbpass)' calls as a result. Finally, any and all testing is always appriciated - but the basics seem to work. Andrew Bartlett (This used to be commit d3dd28f6c443187b8d820d5a39c7c5b3be2fa95c) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 538225e245..a9d80d36fd 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -228,7 +228,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) ZERO_STRUCTP(vuser); if (!IS_SAM_UNIX_USER(server_info->sam_account)) { - DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); + DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT (flags:%x)\n", pdb_get_init_flag(server_info->sam_account))); free(vuser); return UID_FIELD_INVALID; } -- cgit From c311d24ce32d2a8aa244f126bcec67ec03549727 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 17 Jan 2002 08:45:58 +0000 Subject: A nice *big* change to the fundemental way we do things. Samba (ab)uses the returns from getpwnam() a lot - in particular it keeps them around for a long time - often past the next call... This adds a getpwnam_alloc and a getpwuid_alloc to the collection. These function as expected, returning a malloced structure that can be free()ed with passwd_free(&passwd). This patch also cuts down on the number of calls to getpwnam - mostly by taking advantage of the fact that the passdb interface is already case-insensiteve. With this patch most of the recursive cases have been removed (that I know of) and the problems are reduced further by not using the sys_ interface in the new code. This means that pointers to the cache won't be affected. (This is a tempoary HACK, I intend to kill the password cache entirly). The only change I'm a little worried about is the change to rpc_server/srv_samr_nt.c for private groups. In this case we are getting groups from the new group mapping DB. Do we still need to check for private groups? I've toned down the check to a case sensitve match with the new code, but we might be able to kill it entirly. I've also added a make_modifyable_passwd() function, that copies a passwd struct into the form that the old sys_getpw* code provided. As far as I can tell this is only actually used in the pass_check.c crazies, where I moved the final 'special case' for shadow passwords (out of _Get_Pwnam()). The matching case for getpwent() is dealt with already, in lib/util_getent.c Also included in here is a small change to register the [homes] share at vuid creation rather than just in one varient of the session setup. (This picks up the SPNEGO cases). The home directory is now stored on the vuid, and I am hoping this might provide a saner way to do %H substitions. TODO: Kill off remaining Get_Pwnam_Modify calls (they are not needed), change the remaining sys_getpwnam() callers to use getpwnam_alloc() and move Get_Pwnam to return an allocated struct. Andrew Bartlett (This used to be commit 1d86c7f94230bc53daebd4d2cd829da6292e05da) --- source3/smbd/password.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a9d80d36fd..3e942e6f99 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -64,6 +64,8 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; + SAFE_FREE(vuser->homedir); + session_yield(vuser); DLIST_REMOVE(validated_users, vuser); @@ -255,6 +257,14 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); + { + /* Keep the homedir handy */ + const char *homedir = pdb_get_homedir(server_info->sam_account); + if (homedir) { + vuser->homedir = smb_xstrdup(homedir); + } + } + DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, (unsigned int)vuser->gid, @@ -289,6 +299,12 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) return -1; } + /* Register a home dir service for this user */ + if ((!vuser->guest) && vuser->homedir && *(vuser->homedir) + && (lp_servicenumber(vuser->user.unix_name) < 0)) { + add_home_service(vuser->user.unix_name, vuser->homedir); + } + return vuser->vuid; } -- cgit From 32101155d4a0c80faf392f56a6baa7b91847dd99 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sun, 20 Jan 2002 13:26:31 +0000 Subject: Kill off another ugly wart from the side of the passdb subsystem. This time its the pdb_getsampwuid() function - which was only being used by the SAMR rpc subsystem to gain a 'user session key'. This 'user session key' is actually generated at login time, and the other changes here simply move that data around. This also means that (when I check some details) we will be able to use the user session key, even when we are not actually the DC, becouse its one of the components of the info3 struct returned on logon. Andrew Bartlett (This used to be commit 799ac01fe08a338e4e94289f5d6767ebf905c1fa) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3e942e6f99..27bc15d25a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -265,6 +265,8 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) } } + memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key)); + DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, (unsigned int)vuser->gid, -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/smbd/password.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 27bc15d25a..629157f22d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 1.9. + Unix SMB/CIFS implementation. Password and authentication handling Copyright (C) Andrew Tridgell 1992-1998 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/smbd/password.c | 182 +++++++++++++++++++----------------------------- 1 file changed, 73 insertions(+), 109 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 629157f22d..82c0cef77d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -259,9 +259,19 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) { /* Keep the homedir handy */ const char *homedir = pdb_get_homedir(server_info->sam_account); + const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); + const char *logon_script = pdb_get_logon_script(server_info->sam_account); if (homedir) { vuser->homedir = smb_xstrdup(homedir); } + + if (unix_homedir) { + vuser->unix_homedir = smb_xstrdup(unix_homedir); + } + + if (logon_script) { + vuser->logon_script = smb_xstrdup(logon_script); + } } memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key)); @@ -279,7 +289,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) /* Find all the groups this uid is in and store them. Used by change_to_user() */ initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); - get_current_groups( &vuser->n_groups, &vuser->groups); + get_current_groups(vuser->gid, &vuser->n_groups, &vuser->groups); if (server_info->ptok) add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); @@ -301,9 +311,11 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) } /* Register a home dir service for this user */ - if ((!vuser->guest) && vuser->homedir && *(vuser->homedir) + if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir) && (lp_servicenumber(vuser->user.unix_name) < 0)) { - add_home_service(vuser->user.unix_name, vuser->homedir); + vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); + } else { + vuser->homes_snum = -1; } return vuser->vuid; @@ -336,7 +348,7 @@ void add_session_user(char *user) /**************************************************************************** check if a username is valid ****************************************************************************/ -BOOL user_ok(char *user,int snum) +BOOL user_ok(const char *user,int snum) { char **valid, **invalid; BOOL ret; @@ -345,27 +357,27 @@ BOOL user_ok(char *user,int snum) ret = True; if (lp_invalid_users(snum)) { - lp_list_copy(&invalid, lp_invalid_users(snum)); - if (invalid && lp_list_substitute(invalid, "%S", lp_servicename(snum))) { + str_list_copy(&invalid, lp_invalid_users(snum)); + if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { ret = !user_in_list(user, invalid); } } - if (invalid) lp_list_free (&invalid); + if (invalid) str_list_free (&invalid); if (ret && lp_valid_users(snum)) { - lp_list_copy(&valid, lp_valid_users(snum)); - if (valid && lp_list_substitute(valid, "%S", lp_servicename(snum))) { + str_list_copy(&valid, lp_valid_users(snum)); + if (valid && str_list_substitute(valid, "%S", lp_servicename(snum))) { ret = user_in_list(user,valid); } } - if (valid) lp_list_free (&valid); + if (valid) str_list_free (&valid); if (ret && lp_onlyuser(snum)) { - char **user_list = lp_list_make (lp_username(snum)); - if (user_list && lp_list_substitute(user_list, "%S", lp_servicename(snum))) { + char **user_list = str_list_make (lp_username(snum)); + if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { ret = user_in_list(user, user_list); } - if (user_list) lp_list_free (&user_list); + if (user_list) str_list_free (&user_list); } return(ret); @@ -462,42 +474,17 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) ****************************************************************************/ BOOL authorise_login(int snum,char *user, DATA_BLOB password, - BOOL *guest,BOOL *force,uint16 vuid) + BOOL *guest) { BOOL ok = False; - user_struct *vuser = get_valid_user_struct(vuid); - + #if DEBUG_PASSWORD - DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s vuid=%d\n", - user,password.data, vuid)); + DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", + user,password.data)); #endif *guest = False; - if (GUEST_ONLY(snum)) - *force = True; - - if (!GUEST_ONLY(snum) && (lp_security() > SEC_SHARE)) { - - /* - * We should just use the given vuid from a sessionsetup_and_X. - */ - - if (!vuser) { - DEBUG(1,("authorise_login: refusing user '%s' with no session setup\n", user)); - return False; - } - - if ((!vuser->guest && user_ok(vuser->user.unix_name,snum)) || - (vuser->guest && GUEST_OK(snum))) { - fstrcpy(user,vuser->user.unix_name); - *guest = vuser->guest; - DEBUG(3,("authorise_login: ACCEPTED: validated based on vuid as %sguest \ -(user=%s)\n", vuser->guest ? "" : "non-", user)); - return True; - } - } - /* there are several possibilities: 1) login as the given user with given password 2) login as a previously registered username with the given password @@ -510,84 +497,61 @@ BOOL authorise_login(int snum,char *user, DATA_BLOB password, if the service is guest_only then steps 1 to 5 are skipped */ - if (!(GUEST_ONLY(snum) && GUEST_OK(snum))) { - /* check for a previously registered guest username */ - if (!ok && (vuser != 0) && vuser->guest) { - if (user_ok(vuser->user.unix_name,snum) && - password_ok(vuser->user.unix_name, password)) { - fstrcpy(user, vuser->user.unix_name); - *guest = False; - DEBUG(3,("authorise_login: ACCEPTED: given password with registered user %s\n", user)); + /* now check the list of session users */ + if (!ok) { + char *auser; + char *user_list = strdup(session_users); + if (!user_list) + return(False); + + for (auser=strtok(user_list,LIST_SEP); !ok && auser; + auser = strtok(NULL,LIST_SEP)) { + fstring user2; + fstrcpy(user2,auser); + if (!user_ok(user2,snum)) + continue; + + if (password_ok(user2,password)) { ok = True; + fstrcpy(user,user2); + DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ +and given password ok\n", user)); } } - - /* now check the list of session users */ - if (!ok) { - char *auser; - char *user_list = strdup(session_users); - if (!user_list) - return(False); - - for (auser=strtok(user_list,LIST_SEP); !ok && auser; - auser = strtok(NULL,LIST_SEP)) { + + SAFE_FREE(user_list); + } + + /* check the user= fields and the given password */ + if (!ok && lp_username(snum)) { + char *auser; + pstring user_list; + StrnCpy(user_list,lp_username(snum),sizeof(pstring)); + + pstring_sub(user_list,"%S",lp_servicename(snum)); + + for (auser=strtok(user_list,LIST_SEP); auser && !ok; + auser = strtok(NULL,LIST_SEP)) { + if (*auser == '@') { + auser = validate_group(auser+1,password,snum); + if (auser) { + ok = True; + fstrcpy(user,auser); + DEBUG(3,("authorise_login: ACCEPTED: group username \ +and given password ok (%s)\n", user)); + } + } else { fstring user2; fstrcpy(user2,auser); - if (!user_ok(user2,snum)) - continue; - - if (password_ok(user2,password)) { + if (user_ok(user2,snum) && password_ok(user2,password)) { ok = True; fstrcpy(user,user2); - DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ -and given password ok\n", user)); - } - } - - SAFE_FREE(user_list); - } - - /* check for a previously validated username/password pair */ - if (!ok && (lp_security() > SEC_SHARE) && (vuser != 0) && !vuser->guest && - user_ok(vuser->user.unix_name,snum)) { - fstrcpy(user,vuser->user.unix_name); - *guest = False; - DEBUG(3,("authorise_login: ACCEPTED: validated uid (%s) as non-guest\n", - user)); - ok = True; - } - - /* check the user= fields and the given password */ - if (!ok && lp_username(snum)) { - char *auser; - pstring user_list; - StrnCpy(user_list,lp_username(snum),sizeof(pstring)); - - pstring_sub(user_list,"%S",lp_servicename(snum)); - - for (auser=strtok(user_list,LIST_SEP); auser && !ok; - auser = strtok(NULL,LIST_SEP)) { - if (*auser == '@') { - auser = validate_group(auser+1,password,snum); - if (auser) { - ok = True; - fstrcpy(user,auser); - DEBUG(3,("authorise_login: ACCEPTED: group username \ + DEBUG(3,("authorise_login: ACCEPTED: user list username \ and given password ok (%s)\n", user)); - } - } else { - fstring user2; - fstrcpy(user2,auser); - if (user_ok(user2,snum) && password_ok(user2,password)) { - ok = True; - fstrcpy(user,user2); - DEBUG(3,("authorise_login: ACCEPTED: user list username \ -and given password ok (%s)\n", user)); - } } } } - } /* not guest only */ + } /* check for a normal guest connection */ if (!ok && GUEST_OK(snum)) { -- cgit From 127e77e6e334fdc33086bffcbe00d340c0ba0097 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 15:27:10 +0000 Subject: Sync 3.0 branch with head (This used to be commit 42615b945e2e48e53a21ea47f2e45407913a6a1e) --- source3/smbd/password.c | 36 +++++++----------------------------- 1 file changed, 7 insertions(+), 29 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 82c0cef77d..cfac7cf695 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -89,29 +89,6 @@ void invalidate_all_vuids(void) } } -/**************************************************************************** -return a validated username -****************************************************************************/ -char *validated_username(uint16 vuid) -{ - user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) - return 0; - return(vuser->user.unix_name); -} - -/**************************************************************************** -return a validated domain -****************************************************************************/ -char *validated_domain(uint16 vuid) -{ - user_struct *vuser = get_valid_user_struct(vuid); - if (vuser == NULL) - return 0; - return(vuser->user.domain); -} - - /**************************************************************************** Create the SID list for this user. ****************************************************************************/ @@ -207,7 +184,7 @@ has been given. vuid is biased by an offset. This allows us to tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -int register_vuid(auth_serversupplied_info *server_info, char *smb_name) +int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) { user_struct *vuser = NULL; uid_t uid; @@ -297,7 +274,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) /* Create an NT_USER_TOKEN struct for this user. */ vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, vuser->guest, server_info->ptok); - DEBUG(3,("uid %d registered to name %s\n",(int)vuser->uid,vuser->user.unix_name)); + DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid)); next_vuid++; num_validated_vuids++; @@ -311,8 +288,9 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) } /* Register a home dir service for this user */ - if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir) - && (lp_servicenumber(vuser->user.unix_name) < 0)) { + if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { + DEBUG(3, ("Adding/updating homes service for user '%s' using home direcotry: '%s'\n", + vuser->user.unix_name, vuser->unix_homedir)); vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); } else { vuser->homes_snum = -1; @@ -325,7 +303,7 @@ int register_vuid(auth_serversupplied_info *server_info, char *smb_name) /**************************************************************************** add a name to the session users list ****************************************************************************/ -void add_session_user(char *user) +void add_session_user(const char *user) { fstring suser; StrnCpy(suser,user,sizeof(suser)-1); @@ -373,7 +351,7 @@ BOOL user_ok(const char *user,int snum) if (valid) str_list_free (&valid); if (ret && lp_onlyuser(snum)) { - char **user_list = str_list_make (lp_username(snum)); + char **user_list = str_list_make (lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { ret = user_in_list(user, user_list); } -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/smbd/password.c | 162 ++++++++++++------------------------------------ 1 file changed, 41 insertions(+), 121 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index cfac7cf695..f2956237dd 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -69,6 +69,10 @@ void invalidate_vuid(uint16 vuid) DLIST_REMOVE(validated_users, vuser); + /* clear the vuid from the 'cache' on each connection, and + from the vuid 'owner' of connections */ + conn_clear_vuid_cache(vuid); + SAFE_FREE(vuser->groups); delete_nt_token(&vuser->nt_user_token); SAFE_FREE(vuser); @@ -89,95 +93,6 @@ void invalidate_all_vuids(void) } } -/**************************************************************************** - Create the SID list for this user. -****************************************************************************/ - -NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, BOOL is_guest, NT_USER_TOKEN *sup_tok) -{ - extern DOM_SID global_sid_World; - extern DOM_SID global_sid_Network; - extern DOM_SID global_sid_Builtin_Guests; - extern DOM_SID global_sid_Authenticated_Users; - NT_USER_TOKEN *token; - DOM_SID *psids; - int i, psid_ndx = 0; - size_t num_sids = 0; - fstring sid_str; - - if ((token = (NT_USER_TOKEN *)malloc( sizeof(NT_USER_TOKEN) ) ) == NULL) - return NULL; - - ZERO_STRUCTP(token); - - /* We always have uid/gid plus World and Network and Authenticated Users or Guest SIDs. */ - num_sids = 5 + ngroups; - - if (sup_tok && sup_tok->num_sids) - num_sids += sup_tok->num_sids; - - if ((token->user_sids = (DOM_SID *)malloc( num_sids*sizeof(DOM_SID))) == NULL) { - SAFE_FREE(token); - return NULL; - } - - psids = token->user_sids; - - /* - * Note - user SID *MUST* be first in token ! - * se_access_check depends on this. - */ - - uid_to_sid( &psids[PRIMARY_USER_SID_INDEX], uid); - psid_ndx++; - - /* - * Primary group SID is second in token. Convention. - */ - - gid_to_sid( &psids[PRIMARY_GROUP_SID_INDEX], gid); - psid_ndx++; - - /* Now add the group SIDs. */ - - for (i = 0; i < ngroups; i++) { - if (groups[i] != gid) { - gid_to_sid( &psids[psid_ndx++], groups[i]); - } - } - - if (sup_tok) { - /* Now add the additional SIDs from the supplimentary token. */ - for (i = 0; i < sup_tok->num_sids; i++) - sid_copy( &psids[psid_ndx++], &sup_tok->user_sids[i] ); - } - - /* - * Finally add the "standard" SIDs. - * The only difference between guest and "anonymous" (which we - * don't really support) is the addition of Authenticated_Users. - */ - - sid_copy( &psids[psid_ndx++], &global_sid_World); - sid_copy( &psids[psid_ndx++], &global_sid_Network); - - if (is_guest) - sid_copy( &psids[psid_ndx++], &global_sid_Builtin_Guests); - else - sid_copy( &psids[psid_ndx++], &global_sid_Authenticated_Users); - - token->num_sids = psid_ndx; - - /* Dump list of sids in token */ - - for (i = 0; i < token->num_sids; i++) { - DEBUG(5, ("user token sid %s\n", - sid_to_string(sid_str, &token->user_sids[i]))); - } - - return token; -} - /**************************************************************************** register a uid/name pair as being valid and that a valid password has been given. vuid is biased by an offset. This allows us to @@ -187,8 +102,6 @@ tell random client vuid's (normally zero) from valid vuids. int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) { user_struct *vuser = NULL; - uid_t uid; - gid_t gid; /* Ensure no vuid gets registered in share level security. */ if(lp_security() == SEC_SHARE) @@ -205,15 +118,6 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) ZERO_STRUCTP(vuser); - if (!IS_SAM_UNIX_USER(server_info->sam_account)) { - DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT (flags:%x)\n", pdb_get_init_flag(server_info->sam_account))); - free(vuser); - return UID_FIELD_INVALID; - } - - uid = pdb_get_uid(server_info->sam_account); - gid = pdb_get_gid(server_info->sam_account); - /* Allocate a free vuid. Yes this is a linear search... :-) */ while( get_valid_user_struct(next_vuid) != NULL ) { next_vuid++; @@ -225,18 +129,38 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid )); vuser->vuid = next_vuid; - vuser->uid = uid; - vuser->gid = gid; + + /* the next functions should be done by a SID mapping system (SMS) as + * the new real sam db won't have reference to unix uids or gids + */ + if (!IS_SAM_UNIX_USER(server_info->sam_account)) { + DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT (flags:%x)\n", pdb_get_init_flag(server_info->sam_account))); + free(vuser); + return UID_FIELD_INVALID; + } + + vuser->uid = pdb_get_uid(server_info->sam_account); + vuser->gid = pdb_get_gid(server_info->sam_account); + + vuser->n_groups = server_info->n_groups; + if (vuser->n_groups) { + if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { + DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); + free(vuser); + return UID_FIELD_INVALID; + } + } + vuser->guest = server_info->guest; - fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); - fstrcpy(vuser->user.smb_name, smb_name); + fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); + fstrcpy(vuser->user.smb_name, smb_name); fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); { /* Keep the homedir handy */ const char *homedir = pdb_get_homedir(server_info->sam_account); - const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); + const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); /* should be optained by SMS */ const char *logon_script = pdb_get_logon_script(server_info->sam_account); if (homedir) { vuser->homedir = smb_xstrdup(homedir); @@ -260,19 +184,13 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name)); - vuser->n_groups = 0; - vuser->groups = NULL; - - /* Find all the groups this uid is in and store them. - Used by change_to_user() */ - initialise_groups(vuser->user.unix_name, vuser->uid, vuser->gid); - get_current_groups(vuser->gid, &vuser->n_groups, &vuser->groups); - - if (server_info->ptok) - add_supplementary_nt_login_groups(&vuser->n_groups, &vuser->groups, &server_info->ptok); - - /* Create an NT_USER_TOKEN struct for this user. */ - vuser->nt_user_token = create_nt_token(vuser->uid, vuser->gid, vuser->n_groups, vuser->groups, vuser->guest, server_info->ptok); + if (server_info->ptok) { + vuser->nt_user_token = dup_nt_token(server_info->ptok); + } else { + DEBUG(1, ("server_info does not contain a user_token - cannot continue\n")); + free(vuser); + return UID_FIELD_INVALID; + } DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid)); @@ -306,9 +224,11 @@ add a name to the session users list void add_session_user(const char *user) { fstring suser; - StrnCpy(suser,user,sizeof(suser)-1); + struct passwd *passwd; + + if (!(passwd = Get_Pwnam(user))) return; - if (!Get_Pwnam_Modify(suser)) return; + StrnCpy(suser,passwd->pw_name,sizeof(suser)-1); if (suser && *suser && !in_list(suser,session_users,False)) { @@ -451,7 +371,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ -BOOL authorise_login(int snum,char *user, DATA_BLOB password, +BOOL authorise_login(int snum, fstring user, DATA_BLOB password, BOOL *guest) { BOOL ok = False; -- cgit From 6d7195d1d79c43f5ccc8dc4a9215c02177d5fa89 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 2 Nov 2002 03:47:48 +0000 Subject: Merge passdb from HEAD -> 3.0 The work here includes: - metze' set/changed patch, which avoids making changes to ldap on unmodified attributes. - volker's group mapping in passdb patch - volker's samsync stuff - volkers SAMR changes. - mezte's connection caching patch - my recent changes (fix magic root check, ldap ssl) Andrew Bartlett (This used to be commit 2044d60bbe0043cdbb9aba931115672bde975d2f) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f2956237dd..1e87065e31 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -134,7 +134,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) * the new real sam db won't have reference to unix uids or gids */ if (!IS_SAM_UNIX_USER(server_info->sam_account)) { - DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT (flags:%x)\n", pdb_get_init_flag(server_info->sam_account))); + DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); free(vuser); return UID_FIELD_INVALID; } -- cgit From 2f194322d419350f35a48dff750066894d68eccf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 12 Nov 2002 23:20:50 +0000 Subject: Removed global_myworkgroup, global_myname, global_myscope. Added liberal dashes of const. This is a rather large check-in, some things may break. It does compile though :-). Jeremy. (This used to be commit f755711df8f74f9b8e8c1a2b0d07d02a931eeb89) --- source3/smbd/password.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1e87065e31..4ce99e96bb 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -257,23 +257,25 @@ BOOL user_ok(const char *user,int snum) if (lp_invalid_users(snum)) { str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - ret = !user_in_list(user, invalid); + ret = !user_in_list(user, (const char **)invalid); } } - if (invalid) str_list_free (&invalid); + if (invalid) + str_list_free (&invalid); if (ret && lp_valid_users(snum)) { str_list_copy(&valid, lp_valid_users(snum)); if (valid && str_list_substitute(valid, "%S", lp_servicename(snum))) { - ret = user_in_list(user,valid); + ret = user_in_list(user, (const char **)valid); } } - if (valid) str_list_free (&valid); + if (valid) + str_list_free (&valid); if (ret && lp_onlyuser(snum)) { char **user_list = str_list_make (lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { - ret = user_in_list(user, user_list); + ret = user_in_list(user, (const char **)user_list); } if (user_list) str_list_free (&user_list); } -- cgit From e72ecdc862804339912325fe848401e8ec57cde7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:35:54 +0000 Subject: Merge of server-side authentication changes to 3.0: - user_ok() and user_in_group() now take a list of groups, instead of looking for the user in the members of all groups. - The 'server_info' returned from the authentication is now kept around - in future we won't copy the sesion key, username etc, we will just referece them directly. - rhosts upgraded to use the SAM if possible, otherwise fake up based on getpwnam(). - auth_util code to deal with groups upgraded to deal with non-winbind domain members again. Andrew Bartlett (This used to be commit 74b5436c75114170ce7c780c19226103d0df9060) --- source3/smbd/password.c | 59 +++++++++++++++++++++++++++++++++---------------- 1 file changed, 40 insertions(+), 19 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 4ce99e96bb..784c1525c8 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -62,11 +62,15 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; - + SAFE_FREE(vuser->homedir); - + SAFE_FREE(vuser->unix_homedir); + SAFE_FREE(vuser->logon_script); + session_yield(vuser); + free_server_info(&vuser->server_info); + DLIST_REMOVE(validated_users, vuser); /* clear the vuid from the 'cache' on each connection, and @@ -93,11 +97,15 @@ void invalidate_all_vuids(void) } } -/**************************************************************************** -register a uid/name pair as being valid and that a valid password -has been given. vuid is biased by an offset. This allows us to -tell random client vuid's (normally zero) from valid vuids. -****************************************************************************/ +/** + * register that a valid login has been performed, establish 'session'. + * @param server_info The token returned from the authentication process. + * (now 'owned' by register_vuid) + * + * @return Newly allocated vuid, biased by an offset. (This allows us to + * tell random client vuid's (normally zero) from valid vuids.) + * + */ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) { @@ -136,6 +144,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) if (!IS_SAM_UNIX_USER(server_info->sam_account)) { DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); free(vuser); + free_server_info(&server_info); return UID_FIELD_INVALID; } @@ -147,20 +156,24 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); free(vuser); + free_server_info(&server_info); return UID_FIELD_INVALID; } } vuser->guest = server_info->guest; fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); - fstrcpy(vuser->user.smb_name, smb_name); + + /* This is a potentially untrusted username */ + alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", sizeof(vuser->user.smb_name)); + fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); { /* Keep the homedir handy */ const char *homedir = pdb_get_homedir(server_info->sam_account); - const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); /* should be optained by SMS */ + const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); const char *logon_script = pdb_get_logon_script(server_info->sam_account); if (homedir) { vuser->homedir = smb_xstrdup(homedir); @@ -188,10 +201,18 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) vuser->nt_user_token = dup_nt_token(server_info->ptok); } else { DEBUG(1, ("server_info does not contain a user_token - cannot continue\n")); - free(vuser); + free_server_info(&server_info); + SAFE_FREE(vuser->homedir); + SAFE_FREE(vuser->unix_homedir); + SAFE_FREE(vuser->logon_script); + + SAFE_FREE(vuser); return UID_FIELD_INVALID; } + /* use this to keep tabs on all our info from the authentication */ + vuser->server_info = server_info; + DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid)); next_vuid++; @@ -246,7 +267,7 @@ void add_session_user(const char *user) /**************************************************************************** check if a username is valid ****************************************************************************/ -BOOL user_ok(const char *user,int snum) +BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) { char **valid, **invalid; BOOL ret; @@ -257,7 +278,7 @@ BOOL user_ok(const char *user,int snum) if (lp_invalid_users(snum)) { str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - ret = !user_in_list(user, (const char **)invalid); + ret = !user_in_list(user, (const char **)invalid, groups, n_groups); } } if (invalid) @@ -266,7 +287,7 @@ BOOL user_ok(const char *user,int snum) if (ret && lp_valid_users(snum)) { str_list_copy(&valid, lp_valid_users(snum)); if (valid && str_list_substitute(valid, "%S", lp_servicename(snum))) { - ret = user_in_list(user, (const char **)valid); + ret = user_in_list(user, (const char **)valid, groups, n_groups); } } if (valid) @@ -275,7 +296,7 @@ BOOL user_ok(const char *user,int snum) if (ret && lp_onlyuser(snum)) { char **user_list = str_list_make (lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { - ret = user_in_list(user, (const char **)user_list); + ret = user_in_list(user, (const char **)user_list, groups, n_groups); } if (user_list) str_list_free (&user_list); } @@ -294,7 +315,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { - if (user_ok(user, snum) && + if (user_ok(user, snum, NULL, 0) && password_ok(user,password)) { endnetgrent(); return(user); @@ -349,7 +370,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) while (*member) { static fstring name; fstrcpy(name,member); - if (user_ok(name,snum) && + if (user_ok(name,snum, NULL, 0) && password_ok(name,password)) { endgrent(); return(&name[0]); @@ -408,7 +429,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, auser = strtok(NULL,LIST_SEP)) { fstring user2; fstrcpy(user2,auser); - if (!user_ok(user2,snum)) + if (!user_ok(user2,snum, NULL, 0)) continue; if (password_ok(user2,password)) { @@ -443,7 +464,7 @@ and given password ok (%s)\n", user)); } else { fstring user2; fstrcpy(user2,auser); - if (user_ok(user2,snum) && password_ok(user2,password)) { + if (user_ok(user2,snum, NULL, 0) && password_ok(user2,password)) { ok = True; fstrcpy(user,user2); DEBUG(3,("authorise_login: ACCEPTED: user list username \ @@ -468,7 +489,7 @@ and given password ok (%s)\n", user)); *guest = True; } - if (ok && !user_ok(user,snum)) { + if (ok && !user_ok(user, snum, NULL, 0)) { DEBUG(0,("authorise_login: rejected invalid user %s\n",user)); ok = False; } -- cgit From 0e26a6d3f5fc7616ca5caacf3ed39c8c40091c99 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Apr 2003 01:05:26 +0000 Subject: Don't leak the session identifier string when we shut down a vuid. Andrew Bartlett (This used to be commit 33189b4be0ac79d5e7bc2606f40187118ee506a4) --- source3/smbd/password.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 784c1525c8..b47dcc0a97 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -68,6 +68,7 @@ void invalidate_vuid(uint16 vuid) SAFE_FREE(vuser->logon_script); session_yield(vuser); + SAFE_FREE(vuser->session_keystr); free_server_info(&vuser->server_info); -- cgit From 2a3a9f0bf43c3bf99a71f7296bb5ff6199893fea Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 23 Apr 2003 13:27:35 +0000 Subject: Merge the 'safe' parts of my StrnCpy patch - many of the users really wanted a pstrcpy/fstrcpy or at most a safe_strcpy(). These have the advantage of being compiler-verifiable. Get these out of the way, along with a rewrite of 'get_short_archi' in the spoolss client and server. (This pushes around const string pointers, rather than copied strings). Andrew Bartlett (This used to be commit 32fb801ddc035e8971e9911ed4b6e51892e9d1cc) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b47dcc0a97..8dff42471f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -250,7 +250,7 @@ void add_session_user(const char *user) if (!(passwd = Get_Pwnam(user))) return; - StrnCpy(suser,passwd->pw_name,sizeof(suser)-1); + fstrcpy(suser,passwd->pw_name); if (suser && *suser && !in_list(suser,session_users,False)) { @@ -448,7 +448,7 @@ and given password ok\n", user)); if (!ok && lp_username(snum)) { char *auser; pstring user_list; - StrnCpy(user_list,lp_username(snum),sizeof(pstring)); + pstrcpy(user_list,lp_username(snum)); pstring_sub(user_list,"%S",lp_servicename(snum)); @@ -478,7 +478,7 @@ and given password ok (%s)\n", user)); /* check for a normal guest connection */ if (!ok && GUEST_OK(snum)) { fstring guestname; - StrnCpy(guestname,lp_guestaccount(),sizeof(guestname)-1); + fstrcpy(guestname,lp_guestaccount()); if (Get_Pwnam(guestname)) { fstrcpy(user,guestname); ok = True; -- cgit From 9308eaf77d53b2d86c071ef07a8e32d9d83b6d12 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 12 May 2003 16:06:05 +0000 Subject: fixing typos in debug statements (This used to be commit f59bcb51cfe4e268ba43245d401d212aefdf2b72) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8dff42471f..415025f649 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -229,7 +229,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) /* Register a home dir service for this user */ if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { - DEBUG(3, ("Adding/updating homes service for user '%s' using home direcotry: '%s'\n", + DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); } else { -- cgit From c823b191ab476fc2583d6d6aaa1e2edb09cbb88e Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 12 May 2003 18:12:31 +0000 Subject: And finally IDMAP in 3_0 We really need idmap_ldap to have a good solution with ldapsam, porting it from the prvious code is beeing made, the code is really simple to do so I am confident it is not a problem to commit this code in. Not committing it would have been worst. I really would have been able to finish also the group code, maybe we can put it into a followin release after 3.0.0 even if it may be an upgrade problem. The code has been tested and seem to work right, more testing is needed for corner cases. Currently winbind pdc (working only for users and not for groups) is disabled as I was not able to make a complete group code replacement that works somewhat in a week (I have a complete patch, but there are bugs) Simo. (This used to be commit 0e58085978f984436815114a2ec347cf7899a89d) --- source3/smbd/password.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 415025f649..81849b709a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -68,7 +68,6 @@ void invalidate_vuid(uint16 vuid) SAFE_FREE(vuser->logon_script); session_yield(vuser); - SAFE_FREE(vuser->session_keystr); free_server_info(&vuser->server_info); @@ -142,15 +141,9 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) /* the next functions should be done by a SID mapping system (SMS) as * the new real sam db won't have reference to unix uids or gids */ - if (!IS_SAM_UNIX_USER(server_info->sam_account)) { - DEBUG(0,("Attempted session setup with invalid user. No uid/gid in SAM_ACCOUNT\n")); - free(vuser); - free_server_info(&server_info); - return UID_FIELD_INVALID; - } - vuser->uid = pdb_get_uid(server_info->sam_account); - vuser->gid = pdb_get_gid(server_info->sam_account); + vuser->uid = server_info->uid; + vuser->gid = server_info->gid; vuser->n_groups = server_info->n_groups; if (vuser->n_groups) { -- cgit From b47963ae5a90ac54c021c9dd6528079180174cc4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 13 May 2003 15:29:23 +0000 Subject: Restore a number of fixes that idra removed when he merged his idmap-and-the-rest from HEAD. These are correctness fixes that were already in 3.0, and a memory leak fix. The pdb_ldap changes are held back at jerry's request (he is also playing with pdb_ldap ATM). Andrew Bartlett (This used to be commit c7d5e336bd91514a02974044742b058be387e490) --- source3/smbd/password.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 81849b709a..283eed73ef 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -68,6 +68,7 @@ void invalidate_vuid(uint16 vuid) SAFE_FREE(vuser->logon_script); session_yield(vuser); + SAFE_FREE(vuser->session_keystr); free_server_info(&vuser->server_info); -- cgit From 1079bd40c50b75324464ea059141656b23ccf31a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 7 Jun 2003 03:20:09 +0000 Subject: Don't assume that the SAM knows the unix home directory - look it up by getpwnam() if need be. Fixes bug #130 Andrew Bartlett (This used to be commit a4bc789a3993be4b25955c729b533b86dba666f4) --- source3/smbd/password.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 283eed73ef..9560449aa5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -168,16 +168,24 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) { /* Keep the homedir handy */ const char *homedir = pdb_get_homedir(server_info->sam_account); - const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); const char *logon_script = pdb_get_logon_script(server_info->sam_account); + + if (!IS_SAM_DEFAULT(server_info->sam_account, PDB_UNIXHOMEDIR)) { + const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); + if (unix_homedir) { + vuser->unix_homedir = smb_xstrdup(unix_homedir); + } + } else { + struct passwd *passwd = getpwnam_alloc(vuser->user.unix_name); + if (passwd) { + vuser->unix_homedir = smb_xstrdup(passwd->pw_dir); + passwd_free(&passwd); + } + } + if (homedir) { vuser->homedir = smb_xstrdup(homedir); } - - if (unix_homedir) { - vuser->unix_homedir = smb_xstrdup(unix_homedir); - } - if (logon_script) { vuser->logon_script = smb_xstrdup(logon_script); } -- cgit From 6dc3885999b6b69bf9960fda012bece214e27ad5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 3 Jul 2003 14:56:04 +0000 Subject: Missed this in the previous patch - we now have a seperate idea of the 'unix username' from the NT username, in the auth subsystem at least. Andrew Bartlett (This used to be commit df1aa2a669edc9f26007595411720742d7dff5d9) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9560449aa5..e2c143f1e2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -157,7 +157,7 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) } vuser->guest = server_info->guest; - fstrcpy(vuser->user.unix_name, pdb_get_username(server_info->sam_account)); + fstrcpy(vuser->user.unix_name, server_info->unix_name); /* This is a potentially untrusted username */ alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", sizeof(vuser->user.smb_name)); -- cgit From 5b4a2dfd2b7fdc5006452126f3b1b8b4f1bc7fe2 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 17 Jul 2003 18:55:40 +0000 Subject: Formatting tidyups to match the rest of the source. Jeremy. (This used to be commit 86c5ebcf8f5eb57e9885627b3da4e486ee3f62d9) --- source3/smbd/password.c | 56 +++++++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e2c143f1e2..9930fc8c33 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -29,10 +29,11 @@ static int next_vuid = VUID_OFFSET; static int num_validated_vuids; /**************************************************************************** -check if a uid has been validated, and return an pointer to the user_struct -if it has. NULL if not. vuid is biased by an offset. This allows us to -tell random client vuid's (normally zero) from valid vuids. + Check if a uid has been validated, and return an pointer to the user_struct + if it has. NULL if not. vuid is biased by an offset. This allows us to + tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ + user_struct *get_valid_user_struct(uint16 vuid) { user_struct *usp; @@ -54,8 +55,9 @@ user_struct *get_valid_user_struct(uint16 vuid) } /**************************************************************************** -invalidate a uid + Invalidate a uid. ****************************************************************************/ + void invalidate_vuid(uint16 vuid) { user_struct *vuser = get_valid_user_struct(vuid); @@ -85,8 +87,9 @@ void invalidate_vuid(uint16 vuid) } /**************************************************************************** -invalidate all vuid entries for this process + Invalidate all vuid entries for this process. ****************************************************************************/ + void invalidate_all_vuids(void) { user_struct *usp, *next=NULL; @@ -238,38 +241,44 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) vuser->homes_snum = -1; } +#if 0 /* JRATEST. */ + if (lp_server_signing() && !vuser->guest && !srv_signing_active()) { + /* Try and turn on server signing on the first non-guest sessionsetup. */ + srv_set_signing(session_key.data, nt_response); + } +#endif + return vuser->vuid; } - /**************************************************************************** -add a name to the session users list + Add a name to the session users list. ****************************************************************************/ + void add_session_user(const char *user) { - fstring suser; - struct passwd *passwd; + fstring suser; + struct passwd *passwd; - if (!(passwd = Get_Pwnam(user))) return; + if (!(passwd = Get_Pwnam(user))) + return; - fstrcpy(suser,passwd->pw_name); + fstrcpy(suser,passwd->pw_name); - if (suser && *suser && !in_list(suser,session_users,False)) - { - if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring)) - DEBUG(1,("Too many session users??\n")); - else - { - pstrcat(session_users," "); - pstrcat(session_users,suser); + if (suser && *suser && !in_list(suser,session_users,False)) { + if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring)) { + DEBUG(1,("Too many session users??\n")); + } else { + pstrcat(session_users," "); + pstrcat(session_users,suser); + } } - } } - /**************************************************************************** -check if a username is valid + Check if a username is valid. ****************************************************************************/ + BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) { char **valid, **invalid; @@ -308,8 +317,9 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) } /**************************************************************************** -validate a group username entry. Return the username or NULL + Validate a group username entry. Return the username or NULL. ****************************************************************************/ + static char *validate_group(char *group, DATA_BLOB password,int snum) { #ifdef HAVE_NETGROUP -- cgit From 814e987c6241601fb03335b2ba9a633d65cc5e23 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 18 Jul 2003 00:53:34 +0000 Subject: Signing so far... the client code fails on a SMBtrans2 secondary transaction I think (my changes haven't affected this I believe). Initial support on the server side for smbclient. Still doesn't work for w2k clients I think... Work in progress..... (don't change). Jeremy. (This used to be commit e5714edc233424c2f74edb6d658f32f8e0ec9275) --- source3/smbd/password.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9930fc8c33..b988f2ec74 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -111,7 +111,7 @@ void invalidate_all_vuids(void) * */ -int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) +int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name) { user_struct *vuser = NULL; @@ -241,12 +241,10 @@ int register_vuid(auth_serversupplied_info *server_info, const char *smb_name) vuser->homes_snum = -1; } -#if 0 /* JRATEST. */ - if (lp_server_signing() && !vuser->guest && !srv_signing_active()) { + if (lp_server_signing() && !vuser->guest && !srv_is_signing_active()) { /* Try and turn on server signing on the first non-guest sessionsetup. */ - srv_set_signing(session_key.data, nt_response); + srv_set_signing(vuser->session_key, response_blob); } -#endif return vuser->vuid; } -- cgit From 5a74bdd7aaf644fc3de94b26d3c85e088211067a Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 5 Sep 2003 05:32:32 +0000 Subject: fix bug 397: use a variant of alloc_sub_basic() for string lists. (This used to be commit 62d5611df0cf86c267d7fe820822d4d019ae28bd) --- source3/smbd/password.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b988f2ec74..32c24b3d67 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -28,6 +28,9 @@ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; static int num_validated_vuids; +extern userdom_struct current_user_info; + + /**************************************************************************** Check if a uid has been validated, and return an pointer to the user_struct if it has. NULL if not. vuid is biased by an offset. This allows us to @@ -296,7 +299,7 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (ret && lp_valid_users(snum)) { str_list_copy(&valid, lp_valid_users(snum)); - if (valid && str_list_substitute(valid, "%S", lp_servicename(snum))) { + if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) { ret = user_in_list(user, (const char **)valid, groups, n_groups); } } -- cgit From 26e4e6208ae5f0cd4eccbef4fa97446d4f750f00 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 26 Sep 2003 19:28:20 +0000 Subject: Fix for valid users = %S in homes share. Jeremy. (This used to be commit c7f4e56ad5c25d477f20944e5b404ebafda9e1a8) --- source3/smbd/password.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 32c24b3d67..958ed663e6 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -291,7 +291,9 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (lp_invalid_users(snum)) { str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - ret = !user_in_list(user, (const char **)invalid, groups, n_groups); + if ( invalid && str_list_sub_basic(invalid, current_user_info.smb_name) ) { + ret = !user_in_list(user, (const char **)invalid, groups, n_groups); + } } } if (invalid) @@ -299,8 +301,10 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (ret && lp_valid_users(snum)) { str_list_copy(&valid, lp_valid_users(snum)); - if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) { - ret = user_in_list(user, (const char **)valid, groups, n_groups); + if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { + if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) { + ret = user_in_list(user, (const char **)valid, groups, n_groups); + } } } if (valid) -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/smbd/password.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 958ed663e6..494d9ecd43 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -77,6 +77,8 @@ void invalidate_vuid(uint16 vuid) free_server_info(&vuser->server_info); + data_blob_free(&vuser->session_key); + DLIST_REMOVE(validated_users, vuser); /* clear the vuid from the 'cache' on each connection, and @@ -109,25 +111,36 @@ void invalidate_all_vuids(void) * @param server_info The token returned from the authentication process. * (now 'owned' by register_vuid) * + * @param session_key The User session key for the login session (now also 'owned' by register_vuid) + * + * @param respose_blob The NT challenge-response, if available. (May be freed after this call) + * + * @param smb_name The untranslated name of the user + * * @return Newly allocated vuid, biased by an offset. (This allows us to * tell random client vuid's (normally zero) from valid vuids.) * */ -int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob, const char *smb_name) +int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name) { user_struct *vuser = NULL; /* Ensure no vuid gets registered in share level security. */ - if(lp_security() == SEC_SHARE) + if(lp_security() == SEC_SHARE) { + data_blob_free(&session_key); return UID_FIELD_INVALID; + } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ - if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) + if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) { + data_blob_free(&session_key); return UID_FIELD_INVALID; + } if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) { DEBUG(0,("Failed to malloc users struct!\n")); + data_blob_free(&session_key); return UID_FIELD_INVALID; } @@ -156,6 +169,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob if (vuser->n_groups) { if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); + data_blob_free(&session_key); free(vuser); free_server_info(&server_info); return UID_FIELD_INVALID; @@ -197,7 +211,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob } } - memcpy(vuser->session_key, server_info->session_key, sizeof(vuser->session_key)); + vuser->session_key = session_key; DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, @@ -211,6 +225,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB response_blob } else { DEBUG(1, ("server_info does not contain a user_token - cannot continue\n")); free_server_info(&server_info); + data_blob_free(&session_key); SAFE_FREE(vuser->homedir); SAFE_FREE(vuser->unix_homedir); SAFE_FREE(vuser->logon_script); -- cgit From f104d75026957981b944b52eb33f7947f4b42fb8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 27 Jan 2004 15:28:33 +0000 Subject: bug 977 - don't create a homes share for a user if a static share already exists by the same name (This used to be commit 6b89a76aa7efaa0ad7a0139aeb3e4ebf5c01cdcb) --- source3/smbd/password.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 494d9ecd43..36e3fb4738 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -254,7 +254,13 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); - vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); + + /* only add the home directory if there doesn't exist a static share by that name */ + if ( lp_servicenumber(vuser->user.unix_name) == -1 ) { + vuser->homes_snum = add_home_service(vuser->user.unix_name, + vuser->user.unix_name, vuser->unix_homedir); + } + } else { vuser->homes_snum = -1; } -- cgit From aa10de1fe4fafee749fd0a6069d857e7945d751b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 31 Jan 2004 14:44:27 +0000 Subject: cleanup patch for bug 977 so we don't display incorrect debug messages (This used to be commit 11093ecfb7bab1ecb16d19ac00b3e7e38dff43e2) --- source3/smbd/password.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 36e3fb4738..10c6aadb1f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -250,17 +250,21 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, return -1; } - /* Register a home dir service for this user */ - if ((!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { - DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", - vuser->user.unix_name, vuser->unix_homedir)); + /* Register a home dir service for this user iff + (a) This is not a guest connection, + (b) we have a home directory defined, and + (c) there s not an existing static share by that name */ + + if ( (!vuser->guest) + && vuser->unix_homedir + && *(vuser->unix_homedir) + && (lp_servicenumber(vuser->user.unix_name) == -1) ) + { + DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", + vuser->user.unix_name, vuser->unix_homedir)); - /* only add the home directory if there doesn't exist a static share by that name */ - if ( lp_servicenumber(vuser->user.unix_name) == -1 ) { vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); - } - } else { vuser->homes_snum = -1; } -- cgit From c24dccd413c41ed81454bc204c59d1fc17a54a33 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 19 Mar 2004 22:06:54 +0000 Subject: BUG 417: fix %UuGg variables expansion in include lines setging the current_user_info struct in register_vuid() -- shouldn't be any more broken than we were (This used to be commit a90c3bd281e7a62bb8482e42aa3b674eeeb5995a) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 10c6aadb1f..9449113ddc 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -273,6 +273,10 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, /* Try and turn on server signing on the first non-guest sessionsetup. */ srv_set_signing(vuser->session_key, response_blob); } + + /* fill in the current_user_info struct */ + set_current_user_info( &vuser->user ); + return vuser->vuid; } -- cgit From e9a7e67e01c115328f95690cbf63ca1ef0b4d408 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2004 07:33:59 +0000 Subject: Merge from HEAD the SMB signing patch that I developed a couple of weeks ago. This patch re-adds support for 'optional' SMB signing. It also ensures that we are much more careful about when we enable signing, particularly with on-the-fly smb.conf reloads. The client code will now attempt to use smb signing by default, and disable it if the server doesn't correctly support it. Andrew Bartlett (This used to be commit e27b5cbe75d89ec839dafd52dd33101885a4c263) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9449113ddc..ef5d0a97ac 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -269,7 +269,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->homes_snum = -1; } - if (lp_server_signing() && !vuser->guest && !srv_is_signing_active()) { + if (srv_is_signing_negotiated() && !vuser->guest && !srv_signing_started()) { /* Try and turn on server signing on the first non-guest sessionsetup. */ srv_set_signing(vuser->session_key, response_blob); } -- cgit From 5573a9ed661b5b07f52e90516edb3fbe210c9c87 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 14 Apr 2004 22:35:28 +0000 Subject: r225: Patch from Pat.Hayward@propero.net to make the session_users list dynamic. I restricted it to 128k max to prevent DOS attacks. Jeremy. (This used to be commit 70fb2a196d83c4bde11d27608da27f956f3f19b8) --- source3/smbd/password.c | 36 ++++++++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ef5d0a97ac..d15970cbef 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -21,7 +21,8 @@ #include "includes.h" /* users from session setup */ -static pstring session_users=""; +static char *session_userlist = NULL; +static int len_session_userlist = 0; /* this holds info on user ids that are already validated for this VC */ static user_struct *validated_users; @@ -295,14 +296,33 @@ void add_session_user(const char *user) fstrcpy(suser,passwd->pw_name); - if (suser && *suser && !in_list(suser,session_users,False)) { - if (strlen(suser) + strlen(session_users) + 2 >= sizeof(pstring)) { - DEBUG(1,("Too many session users??\n")); - } else { - pstrcat(session_users," "); - pstrcat(session_users,suser); + if(!*suser) + return; + + if( session_userlist && in_list(suser,session_userlist,False) ) + return; + + if( !session_userlist || (strlen(suser) + strlen(session_userlist) + 2 >= len_session_userlist) ) { + char *newlist; + + if (len_session_userlist > 128 * PSTRING_LEN) { + DEBUG(3,("add_session_user: session userlist already too large.\n")); + return; + } + newlist = Realloc( session_userlist, len_session_userlist + PSTRING_LEN ); + if( newlist == NULL ) { + DEBUG(1,("Unable to resize session_userlist\n")); + return; } + if (!session_userlist) { + *newlist = '\0'; + } + session_userlist = newlist; + len_session_userlist += PSTRING_LEN; } + + safe_strcat(session_userlist," ",len_session_userlist-1); + safe_strcat(session_userlist,suser,len_session_userlist-1); } /**************************************************************************** @@ -468,7 +488,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, /* now check the list of session users */ if (!ok) { char *auser; - char *user_list = strdup(session_users); + char *user_list = strdup(session_userlist); if (!user_list) return(False); -- cgit From c2c069d4b0fc6e29194a8ba8d12b8aba59dae4c2 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 5 May 2004 02:58:43 +0000 Subject: r486: BUG 1309: fix seg fault caused by trying to strdup() a NULL pointer (This used to be commit 0e1a6b34f2690da32bf568330575651988d0c965) --- source3/smbd/password.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index d15970cbef..72292de422 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -488,7 +488,11 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, /* now check the list of session users */ if (!ok) { char *auser; - char *user_list = strdup(session_userlist); + char *user_list = NULL; + + if ( session_userlist ) + user_list = strdup(session_userlist); + if (!user_list) return(False); -- cgit From ad770b098c5079accc9d64c28855daca3c2bbfa1 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 6 May 2004 15:29:02 +0000 Subject: r519: fix bug in authorise_login() that broke security = share (This used to be commit b27192d8e7a4a1fd0cd737b4fd9190bcecfbb507) --- source3/smbd/password.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 72292de422..b2dbde151d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -492,6 +492,8 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, if ( session_userlist ) user_list = strdup(session_userlist); + else + user_list = strdup(""); if (!user_list) return(False); -- cgit From f7463e1bcd956305efe187b958bbd479cca4a820 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 15 Jul 2004 00:58:35 +0000 Subject: r1506: Fix inspired by patches from Michael Collin Nielsen - ensure home directory service number is correctly reused. Jeremy. (This used to be commit 9d6347be8580d092cda0357b5d1a81fc6876ac1f) --- source3/smbd/password.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b2dbde151d..3be1516cf0 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -253,19 +253,23 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, /* Register a home dir service for this user iff (a) This is not a guest connection, - (b) we have a home directory defined, and - (c) there s not an existing static share by that name */ - - if ( (!vuser->guest) - && vuser->unix_homedir - && *(vuser->unix_homedir) - && (lp_servicenumber(vuser->user.unix_name) == -1) ) - { - DEBUG(3, ("Adding/updating homes service for user '%s' using home directory: '%s'\n", + (b) we have a home directory defined + If a share exists by this name (autoloaded or not) reuse it so + long as the home directory is the same as the share directory. */ + + if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { + int servicenumber = lp_servicenumber(vuser->user.unix_name); + if ( servicenumber == -1 ) { + DEBUG(3, ("Adding homes service for user '%s' using home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); - vuser->homes_snum = add_home_service(vuser->user.unix_name, - vuser->user.unix_name, vuser->unix_homedir); + vuser->user.unix_name, vuser->unix_homedir); + } else if (strcmp(lp_pathname(servicenumber),vuser->unix_homedir) == 0) { + DEBUG(3, ("Reusing homes service for user '%s' using home directory: '%s'\n", + vuser->user.unix_name, vuser->unix_homedir)); + + vuser->homes_snum = servicenumber; + } } else { vuser->homes_snum = -1; } -- cgit From df5ee6a6ba2ebe445c8889625c2ee36eea81fcc8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 26 Aug 2004 20:47:58 +0000 Subject: r2077: fix logic bug in the check for creating a user's home directory in register_vuid(); add a few extra debug lines (This used to be commit 02571e7f5040a577840c969ff9c46a1e533edc21) --- source3/smbd/password.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 3be1516cf0..decac845ac 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -252,27 +252,30 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, } /* Register a home dir service for this user iff + (a) This is not a guest connection, (b) we have a home directory defined - If a share exists by this name (autoloaded or not) reuse it so - long as the home directory is the same as the share directory. */ + (c) there s not an existing static share by that name + + If a share exists by this name (autoloaded or not) reuse it . */ + + vuser->homes_snum = -1; - if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { + if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) + { int servicenumber = lp_servicenumber(vuser->user.unix_name); + if ( servicenumber == -1 ) { DEBUG(3, ("Adding homes service for user '%s' using home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); vuser->homes_snum = add_home_service(vuser->user.unix_name, vuser->user.unix_name, vuser->unix_homedir); - } else if (strcmp(lp_pathname(servicenumber),vuser->unix_homedir) == 0) { - DEBUG(3, ("Reusing homes service for user '%s' using home directory: '%s'\n", - vuser->user.unix_name, vuser->unix_homedir)); - + } else { + DEBUG(3, ("Using static (or previously created) service for user '%s'; path = '%s'\n", + vuser->user.unix_name, lp_path(servicenumber) )); vuser->homes_snum = servicenumber; } - } else { - vuser->homes_snum = -1; - } + } if (srv_is_signing_negotiated() && !vuser->guest && !srv_signing_started()) { /* Try and turn on server signing on the first non-guest sessionsetup. */ -- cgit From 5ef08833b8aea6fffe19173349c0ac9b50994b5f Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 Aug 2004 21:39:10 +0000 Subject: r2082: lp_path should be lp_pathname. Paranoia fix on mangle prefix. Jeremy. (This used to be commit cc91bbe20d9cb26e52ad417f279e2d60c85af2dc) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index decac845ac..cf3c3d64d2 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -272,7 +272,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->user.unix_name, vuser->unix_homedir); } else { DEBUG(3, ("Using static (or previously created) service for user '%s'; path = '%s'\n", - vuser->user.unix_name, lp_path(servicenumber) )); + vuser->user.unix_name, lp_pathname(servicenumber) )); vuser->homes_snum = servicenumber; } } -- cgit From 8f49721fef2dfa66ac13ec7b860a3315019240da Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Mon, 11 Oct 2004 00:32:31 +0000 Subject: r2899: Change some #if DEBUG_PASSWORD's to #ifdef DEBUG_PASSWORD. Bugzilla #1903. (This used to be commit 1327d83d902b6a39096d387d734e73d85ed53f85) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index cf3c3d64d2..eb389d7013 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -473,7 +473,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, { BOOL ok = False; -#if DEBUG_PASSWORD +#ifdef DEBUG_PASSWORD DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", user,password.data)); #endif -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/smbd/password.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index eb389d7013..213ef98ea3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -139,7 +139,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, return UID_FIELD_INVALID; } - if((vuser = (user_struct *)malloc( sizeof(user_struct) )) == NULL) { + if((vuser = SMB_MALLOC_P(user_struct)) == NULL) { DEBUG(0,("Failed to malloc users struct!\n")); data_blob_free(&session_key); return UID_FIELD_INVALID; @@ -316,7 +316,7 @@ void add_session_user(const char *user) DEBUG(3,("add_session_user: session userlist already too large.\n")); return; } - newlist = Realloc( session_userlist, len_session_userlist + PSTRING_LEN ); + newlist = SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); if( newlist == NULL ) { DEBUG(1,("Unable to resize session_userlist\n")); return; @@ -498,9 +498,9 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, char *user_list = NULL; if ( session_userlist ) - user_list = strdup(session_userlist); + user_list = SMB_STRDUP(session_userlist); else - user_list = strdup(""); + user_list = SMB_STRDUP(""); if (!user_list) return(False); -- cgit From 19ca97a70f6b7b41d251eaa76e4d3c980c6eedff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 24 Jun 2005 20:25:18 +0000 Subject: r7882: Looks like a large patch - but what it actually does is make Samba safe for using our headers and linking with C++ modules. Stops us from using C++ reserved keywords in our code. Jeremy (This used to be commit 9506b8e145982b1160a2f0aee5c9b7a54980940a) --- source3/smbd/password.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 213ef98ea3..2ee8c1232e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -168,7 +168,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->n_groups = server_info->n_groups; if (vuser->n_groups) { - if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { + if (!(vuser->groups = (gid_t *)memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); data_blob_free(&session_key); free(vuser); @@ -316,7 +316,7 @@ void add_session_user(const char *user) DEBUG(3,("add_session_user: session userlist already too large.\n")); return; } - newlist = SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); + newlist = (char *)SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); if( newlist == NULL ) { DEBUG(1,("Unable to resize session_userlist\n")); return; -- cgit From dae78e57e2341e519a2bb609d827968ac93a2499 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 14 Jul 2005 14:39:27 +0000 Subject: r8472: abartlet's patch for parallel ntlmssp supporttrunk/source/smbd/sesssetup.c (This used to be commit aab17a7095a18b243a271f8f3f824facd6932f23) --- source3/smbd/password.c | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2ee8c1232e..9ee721089c 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -47,7 +47,31 @@ user_struct *get_valid_user_struct(uint16 vuid) return NULL; for (usp=validated_users;usp;usp=usp->next,count++) { - if (vuid == usp->vuid) { + if (vuid == usp->vuid && usp->server_info) { + if (count > 10) { + DLIST_PROMOTE(validated_users, usp); + } + return usp; + } + } + + return NULL; +} + +/**************************************************************************** + Get the user struct of a partial NTLMSSP login +****************************************************************************/ + +user_struct *get_partial_auth_user_struct(uint16 vuid) +{ + user_struct *usp; + int count=0; + + if (vuid == UID_FIELD_INVALID) + return NULL; + + for (usp=validated_users;usp;usp=usp->next,count++) { + if (vuid == usp->vuid && !usp->server_info) { if (count > 10) { DLIST_PROMOTE(validated_users, usp); } @@ -159,6 +183,17 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->vuid = next_vuid; + if (!server_info) { + next_vuid++; + num_validated_vuids++; + + vuser->server_info = NULL; + + DLIST_ADD(validated_users, vuser); + + return vuser->vuid; + } + /* the next functions should be done by a SID mapping system (SMS) as * the new real sam db won't have reference to unix uids or gids */ -- cgit From b15c32800dd509bf63d7eab52b620e2ac289e95a Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 17 Dec 2005 16:31:04 +0000 Subject: r12305: Reformatting (This used to be commit f574e980aac5bae5e1e3cc23ec648b69a87eb04a) --- source3/smbd/password.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 9ee721089c..e4516be32b 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -381,9 +381,14 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (lp_invalid_users(snum)) { str_list_copy(&invalid, lp_invalid_users(snum)); - if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - if ( invalid && str_list_sub_basic(invalid, current_user_info.smb_name) ) { - ret = !user_in_list(user, (const char **)invalid, groups, n_groups); + if (invalid && + str_list_substitute(invalid, "%S", lp_servicename(snum))) { + if ( invalid && + str_list_sub_basic(invalid, + current_user_info.smb_name) ) { + ret = !user_in_list(user, + (const char **)invalid, + groups, n_groups); } } } @@ -392,9 +397,13 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (ret && lp_valid_users(snum)) { str_list_copy(&valid, lp_valid_users(snum)); - if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { - if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) { - ret = user_in_list(user, (const char **)valid, groups, n_groups); + if ( valid && + str_list_substitute(valid, "%S", lp_servicename(snum)) ) { + if ( valid && + str_list_sub_basic(valid, + current_user_info.smb_name) ) { + ret = user_in_list(user, (const char **)valid, + groups, n_groups); } } } @@ -403,8 +412,11 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (ret && lp_onlyuser(snum)) { char **user_list = str_list_make (lp_username(snum), NULL); - if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { - ret = user_in_list(user, (const char **)user_list, groups, n_groups); + if (user_list && + str_list_substitute(user_list, "%S", + lp_servicename(snum))) { + ret = user_in_list(user, (const char **)user_list, + groups, n_groups); } if (user_list) str_list_free (&user_list); } -- cgit From 46dee7219da466e292c865fa7e24bc8634197875 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 18 Dec 2005 13:54:53 +0000 Subject: r12311: Reformatting (This used to be commit 23f5be1dcbb9e5a1e7f24813c67009056b07d59c) --- source3/smbd/password.c | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e4516be32b..764fbe8a2e 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -521,19 +521,21 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, BOOL ok = False; #ifdef DEBUG_PASSWORD - DEBUG(100,("authorise_login: checking authorisation on user=%s pass=%s\n", - user,password.data)); + DEBUG(100,("authorise_login: checking authorisation on " + "user=%s pass=%s\n", user,password.data)); #endif *guest = False; /* there are several possibilities: 1) login as the given user with given password - 2) login as a previously registered username with the given password + 2) login as a previously registered username with the given + password 3) login as a session list username with the given password 4) login as a previously validated user/password pair 5) login as the "user =" user with given password - 6) login as the "user =" user with no password (guest connection) + 6) login as the "user =" user with no password + (guest connection) 7) login as guest user with no password if the service is guest_only then steps 1 to 5 are skipped @@ -562,11 +564,12 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, if (password_ok(user2,password)) { ok = True; fstrcpy(user,user2); - DEBUG(3,("authorise_login: ACCEPTED: session list username (%s) \ -and given password ok\n", user)); + DEBUG(3,("authorise_login: ACCEPTED: session " + "list username (%s) and given " + "password ok\n", user)); } } - + SAFE_FREE(user_list); } @@ -585,17 +588,21 @@ and given password ok\n", user)); if (auser) { ok = True; fstrcpy(user,auser); - DEBUG(3,("authorise_login: ACCEPTED: group username \ -and given password ok (%s)\n", user)); + DEBUG(3,("authorise_login: ACCEPTED: " + "group username and given " + "password ok (%s)\n", user)); } } else { fstring user2; fstrcpy(user2,auser); - if (user_ok(user2,snum, NULL, 0) && password_ok(user2,password)) { + if (user_ok(user2,snum, NULL, 0) && + password_ok(user2,password)) { ok = True; fstrcpy(user,user2); - DEBUG(3,("authorise_login: ACCEPTED: user list username \ -and given password ok (%s)\n", user)); + DEBUG(3,("authorise_login: ACCEPTED: " + "user list username and " + "given password ok (%s)\n", + user)); } } } @@ -608,10 +615,11 @@ and given password ok (%s)\n", user)); if (Get_Pwnam(guestname)) { fstrcpy(user,guestname); ok = True; - DEBUG(3,("authorise_login: ACCEPTED: guest account and guest ok (%s)\n", - user)); + DEBUG(3,("authorise_login: ACCEPTED: guest account " + "and guest ok (%s)\n", user)); } else { - DEBUG(0,("authorise_login: Invalid guest account %s??\n",guestname)); + DEBUG(0,("authorise_login: Invalid guest account " + "%s??\n",guestname)); } *guest = True; } -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/smbd/password.c | 143 ++++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 54 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 764fbe8a2e..e644550400 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -100,7 +100,7 @@ void invalidate_vuid(uint16 vuid) session_yield(vuser); SAFE_FREE(vuser->session_keystr); - free_server_info(&vuser->server_info); + talloc_free(vuser->server_info); data_blob_free(&vuser->session_key); @@ -111,7 +111,7 @@ void invalidate_vuid(uint16 vuid) conn_clear_vuid_cache(vuid); SAFE_FREE(vuser->groups); - delete_nt_token(&vuser->nt_user_token); + talloc_free(vuser->nt_user_token); SAFE_FREE(vuser); num_validated_vuids--; } @@ -136,9 +136,11 @@ void invalidate_all_vuids(void) * @param server_info The token returned from the authentication process. * (now 'owned' by register_vuid) * - * @param session_key The User session key for the login session (now also 'owned' by register_vuid) + * @param session_key The User session key for the login session (now also + * 'owned' by register_vuid) * - * @param respose_blob The NT challenge-response, if available. (May be freed after this call) + * @param respose_blob The NT challenge-response, if available. (May be + * freed after this call) * * @param smb_name The untranslated name of the user * @@ -147,7 +149,9 @@ void invalidate_all_vuids(void) * */ -int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name) +int register_vuid(auth_serversupplied_info *server_info, + DATA_BLOB session_key, DATA_BLOB response_blob, + const char *smb_name) { user_struct *vuser = NULL; @@ -179,7 +183,8 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, next_vuid = VUID_OFFSET; } - DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid )); + DEBUG(10,("register_vuid: allocated vuid = %u\n", + (unsigned int)next_vuid )); vuser->vuid = next_vuid; @@ -203,11 +208,14 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, vuser->n_groups = server_info->n_groups; if (vuser->n_groups) { - if (!(vuser->groups = (gid_t *)memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) { - DEBUG(0,("register_vuid: failed to memdup vuser->groups\n")); + if (!(vuser->groups = (gid_t *)memdup(server_info->groups, + sizeof(gid_t) * + vuser->n_groups))) { + DEBUG(0,("register_vuid: failed to memdup " + "vuser->groups\n")); data_blob_free(&session_key); free(vuser); - free_server_info(&server_info); + talloc_free(server_info); return UID_FIELD_INVALID; } } @@ -216,26 +224,35 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, fstrcpy(vuser->user.unix_name, server_info->unix_name); /* This is a potentially untrusted username */ - alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", sizeof(vuser->user.smb_name)); + alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", + sizeof(vuser->user.smb_name)); fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); - fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); + fstrcpy(vuser->user.full_name, + pdb_get_fullname(server_info->sam_account)); { /* Keep the homedir handy */ - const char *homedir = pdb_get_homedir(server_info->sam_account); - const char *logon_script = pdb_get_logon_script(server_info->sam_account); - - if (!IS_SAM_DEFAULT(server_info->sam_account, PDB_UNIXHOMEDIR)) { - const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); + const char *homedir = + pdb_get_homedir(server_info->sam_account); + const char *logon_script = + pdb_get_logon_script(server_info->sam_account); + + if (!IS_SAM_DEFAULT(server_info->sam_account, + PDB_UNIXHOMEDIR)) { + const char *unix_homedir = + pdb_get_unix_homedir(server_info->sam_account); if (unix_homedir) { - vuser->unix_homedir = smb_xstrdup(unix_homedir); + vuser->unix_homedir = + smb_xstrdup(unix_homedir); } } else { - struct passwd *passwd = getpwnam_alloc(vuser->user.unix_name); + struct passwd *passwd = + getpwnam_alloc(NULL, vuser->user.unix_name); if (passwd) { - vuser->unix_homedir = smb_xstrdup(passwd->pw_dir); - passwd_free(&passwd); + vuser->unix_homedir = + smb_xstrdup(passwd->pw_dir); + talloc_free(passwd); } } @@ -252,15 +269,18 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->uid, (unsigned int)vuser->gid, - vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, vuser->guest )); + vuser->user.unix_name, vuser->user.smb_name, + vuser->user.domain, vuser->guest )); - DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name)); + DEBUG(3, ("User name: %s\tReal name: %s\n", vuser->user.unix_name, + vuser->user.full_name)); if (server_info->ptok) { - vuser->nt_user_token = dup_nt_token(server_info->ptok); + vuser->nt_user_token = dup_nt_token(NULL, server_info->ptok); } else { - DEBUG(1, ("server_info does not contain a user_token - cannot continue\n")); - free_server_info(&server_info); + DEBUG(1, ("server_info does not contain a user_token - " + "cannot continue\n")); + talloc_free(server_info); data_blob_free(&session_key); SAFE_FREE(vuser->homedir); SAFE_FREE(vuser->unix_homedir); @@ -273,7 +293,8 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, /* use this to keep tabs on all our info from the authentication */ vuser->server_info = server_info; - DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid)); + DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n", + (int)vuser->uid,vuser->user.unix_name, vuser->vuid)); next_vuid++; num_validated_vuids++; @@ -281,7 +302,8 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DLIST_ADD(validated_users, vuser); if (!session_claim(vuser)) { - DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid)); + DEBUG(1, ("Failed to claim session for vuid=%d\n", + vuser->vuid)); invalidate_vuid(vuser->vuid); return -1; } @@ -301,19 +323,26 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, int servicenumber = lp_servicenumber(vuser->user.unix_name); if ( servicenumber == -1 ) { - DEBUG(3, ("Adding homes service for user '%s' using home directory: '%s'\n", + DEBUG(3, ("Adding homes service for user '%s' using " + "home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); - vuser->homes_snum = add_home_service(vuser->user.unix_name, - vuser->user.unix_name, vuser->unix_homedir); + vuser->homes_snum = + add_home_service(vuser->user.unix_name, + vuser->user.unix_name, + vuser->unix_homedir); } else { - DEBUG(3, ("Using static (or previously created) service for user '%s'; path = '%s'\n", - vuser->user.unix_name, lp_pathname(servicenumber) )); + DEBUG(3, ("Using static (or previously created) " + "service for user '%s'; path = '%s'\n", + vuser->user.unix_name, + lp_pathname(servicenumber) )); vuser->homes_snum = servicenumber; } } - if (srv_is_signing_negotiated() && !vuser->guest && !srv_signing_started()) { - /* Try and turn on server signing on the first non-guest sessionsetup. */ + if (srv_is_signing_negotiated() && !vuser->guest && + !srv_signing_started()) { + /* Try and turn on server signing on the first non-guest + * sessionsetup. */ srv_set_signing(vuser->session_key, response_blob); } @@ -344,14 +373,19 @@ void add_session_user(const char *user) if( session_userlist && in_list(suser,session_userlist,False) ) return; - if( !session_userlist || (strlen(suser) + strlen(session_userlist) + 2 >= len_session_userlist) ) { + if( !session_userlist || + (strlen(suser) + strlen(session_userlist) + 2 >= + len_session_userlist) ) { char *newlist; if (len_session_userlist > 128 * PSTRING_LEN) { - DEBUG(3,("add_session_user: session userlist already too large.\n")); + DEBUG(3,("add_session_user: session userlist already " + "too large.\n")); return; } - newlist = (char *)SMB_REALLOC( session_userlist, len_session_userlist + PSTRING_LEN ); + newlist = (char *)SMB_REALLOC( + session_userlist, + len_session_userlist + PSTRING_LEN ); if( newlist == NULL ) { DEBUG(1,("Unable to resize session_userlist\n")); return; @@ -371,7 +405,7 @@ void add_session_user(const char *user) Check if a username is valid. ****************************************************************************/ -BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) +static BOOL user_ok(const char *user, int snum) { char **valid, **invalid; BOOL ret; @@ -387,8 +421,7 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) str_list_sub_basic(invalid, current_user_info.smb_name) ) { ret = !user_in_list(user, - (const char **)invalid, - groups, n_groups); + (const char **)invalid); } } } @@ -402,8 +435,7 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if ( valid && str_list_sub_basic(valid, current_user_info.smb_name) ) { - ret = user_in_list(user, (const char **)valid, - groups, n_groups); + ret = user_in_list(user, (const char **)valid); } } } @@ -415,8 +447,7 @@ BOOL user_ok(const char *user,int snum, gid_t *groups, size_t n_groups) if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { - ret = user_in_list(user, (const char **)user_list, - groups, n_groups); + ret = user_in_list(user, (const char **)user_list); } if (user_list) str_list_free (&user_list); } @@ -436,7 +467,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) setnetgrent(group); while (getnetgrent(&host, &user, &domain)) { if (user) { - if (user_ok(user, snum, NULL, 0) && + if (user_ok(user, snum) && password_ok(user,password)) { endnetgrent(); return(user); @@ -472,12 +503,15 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) member = member_list; for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { - size_t member_len = strlen(gptr->gr_mem[i]) + 1; - if( copied_len + member_len < sizeof(pstring)) { + size_t member_len = strlen(gptr->gr_mem[i])+1; + if(copied_len+member_len < sizeof(pstring)) { - DEBUG(10,("validate_group: = gr_mem = %s\n", gptr->gr_mem[i])); + DEBUG(10,("validate_group: = gr_mem = " + "%s\n", gptr->gr_mem[i])); - safe_strcpy(member, gptr->gr_mem[i], sizeof(pstring) - copied_len - 1); + safe_strcpy(member, gptr->gr_mem[i], + sizeof(pstring) - + copied_len - 1); copied_len += member_len; member += copied_len; } else { @@ -491,13 +525,14 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) while (*member) { static fstring name; fstrcpy(name,member); - if (user_ok(name,snum, NULL, 0) && + if (user_ok(name,snum) && password_ok(name,password)) { endgrent(); return(&name[0]); } - DEBUG(10,("validate_group = member = %s\n", member)); + DEBUG(10,("validate_group = member = %s\n", + member)); member += strlen(member) + 1; } @@ -558,7 +593,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, auser = strtok(NULL,LIST_SEP)) { fstring user2; fstrcpy(user2,auser); - if (!user_ok(user2,snum, NULL, 0)) + if (!user_ok(user2,snum)) continue; if (password_ok(user2,password)) { @@ -595,7 +630,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, } else { fstring user2; fstrcpy(user2,auser); - if (user_ok(user2,snum, NULL, 0) && + if (user_ok(user2,snum) && password_ok(user2,password)) { ok = True; fstrcpy(user,user2); @@ -624,7 +659,7 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, *guest = True; } - if (ok && !user_ok(user, snum, NULL, 0)) { + if (ok && !user_ok(user, snum)) { DEBUG(0,("authorise_login: rejected invalid user %s\n",user)); ok = False; } -- cgit From 301d51e13a1aa4e633e2da161b0dd260a8a499cd Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 13 Feb 2006 17:08:25 +0000 Subject: r13494: Merge the stuff I've done in head the last days. Volker (This used to be commit bb40e544de68f01a6e774753f508e69373b39899) --- source3/smbd/password.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index e644550400..0eeb537ded 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -401,6 +401,135 @@ void add_session_user(const char *user) safe_strcat(session_userlist,suser,len_session_userlist-1); } +/**************************************************************************** + Check if a user is in a netgroup user list. If at first we don't succeed, + try lower case. +****************************************************************************/ + +BOOL user_in_netgroup(const char *user, const char *ngname) +{ +#ifdef HAVE_NETGROUP + static char *mydomain = NULL; + fstring lowercase_user; + + if (mydomain == NULL) + yp_get_default_domain(&mydomain); + + if(mydomain == NULL) { + DEBUG(5,("Unable to get default yp domain\n")); + return False; + } + + DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", + user, mydomain, ngname)); + + if (innetgr(ngname, NULL, user, mydomain)) { + DEBUG(5,("user_in_netgroup: Found\n")); + return (True); + } else { + + /* + * Ok, innetgr is case sensitive. Try once more with lowercase + * just in case. Attempt to fix #703. JRA. + */ + + fstrcpy(lowercase_user, user); + strlower_m(lowercase_user); + + DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", + lowercase_user, mydomain, ngname)); + + if (innetgr(ngname, NULL, lowercase_user, mydomain)) { + DEBUG(5,("user_in_netgroup: Found\n")); + return (True); + } + } +#endif /* HAVE_NETGROUP */ + return False; +} + +/**************************************************************************** + Check if a user is in a user list - can check combinations of UNIX + and netgroup lists. +****************************************************************************/ + +BOOL user_in_list(const char *user,const char **list) +{ + if (!list || !*list) + return False; + + DEBUG(10,("user_in_list: checking user %s in list\n", user)); + + while (*list) { + + DEBUG(10,("user_in_list: checking user |%s| against |%s|\n", + user, *list)); + + /* + * Check raw username. + */ + if (strequal(user, *list)) + return(True); + + /* + * Now check to see if any combination + * of UNIX and netgroups has been specified. + */ + + if(**list == '@') { + /* + * Old behaviour. Check netgroup list + * followed by UNIX list. + */ + if(user_in_netgroup(user, *list +1)) + return True; + if(user_in_group(user, *list +1)) + return True; + } else if (**list == '+') { + + if((*(*list +1)) == '&') { + /* + * Search UNIX list followed by netgroup. + */ + if(user_in_group(user, *list +2)) + return True; + if(user_in_netgroup(user, *list +2)) + return True; + + } else { + + /* + * Just search UNIX list. + */ + + if(user_in_group(user, *list +1)) + return True; + } + + } else if (**list == '&') { + + if(*(*list +1) == '+') { + /* + * Search netgroup list followed by UNIX list. + */ + if(user_in_netgroup(user, *list +2)) + return True; + if(user_in_group(user, *list +2)) + return True; + } else { + /* + * Just search netgroup list. + */ + if(user_in_netgroup(user, *list +1)) + return True; + } + } + + list++; + } + return(False); +} + /**************************************************************************** Check if a username is valid. ****************************************************************************/ -- cgit From fb5362c069b5b6548478b2217a0519c56d856705 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Mon, 20 Feb 2006 17:59:58 +0000 Subject: r13571: Replace all calls to talloc_free() with thye TALLOC_FREE() macro which sets the freed pointer to NULL. (This used to be commit b65be8874a2efe5a4b167448960a4fcf6bd995e2) --- source3/smbd/password.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 0eeb537ded..782a8c2b89 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -100,7 +100,7 @@ void invalidate_vuid(uint16 vuid) session_yield(vuser); SAFE_FREE(vuser->session_keystr); - talloc_free(vuser->server_info); + TALLOC_FREE(vuser->server_info); data_blob_free(&vuser->session_key); @@ -111,7 +111,7 @@ void invalidate_vuid(uint16 vuid) conn_clear_vuid_cache(vuid); SAFE_FREE(vuser->groups); - talloc_free(vuser->nt_user_token); + TALLOC_FREE(vuser->nt_user_token); SAFE_FREE(vuser); num_validated_vuids--; } @@ -215,7 +215,7 @@ int register_vuid(auth_serversupplied_info *server_info, "vuser->groups\n")); data_blob_free(&session_key); free(vuser); - talloc_free(server_info); + TALLOC_FREE(server_info); return UID_FIELD_INVALID; } } @@ -252,7 +252,7 @@ int register_vuid(auth_serversupplied_info *server_info, if (passwd) { vuser->unix_homedir = smb_xstrdup(passwd->pw_dir); - talloc_free(passwd); + TALLOC_FREE(passwd); } } @@ -280,7 +280,7 @@ int register_vuid(auth_serversupplied_info *server_info, } else { DEBUG(1, ("server_info does not contain a user_token - " "cannot continue\n")); - talloc_free(server_info); + TALLOC_FREE(server_info); data_blob_free(&session_key); SAFE_FREE(vuser->homedir); SAFE_FREE(vuser->unix_homedir); -- cgit From 894358a8f3e338b339b6c37233edef794b312087 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Mar 2006 06:31:04 +0000 Subject: r13915: Fixed a very interesting class of realloc() bugs found by Coverity. realloc can return NULL in one of two cases - (1) the realloc failed, (2) realloc succeeded but the new size requested was zero, in which case this is identical to a free() call. The error paths dealing with these two cases should be different, but mostly weren't. Secondly the standard idiom for dealing with realloc when you know the new size is non-zero is the following : tmp = realloc(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } However, there were *many* *many* places in Samba where we were using the old (broken) idiom of : p = realloc(p, size) if (!p) { return error; } which will leak the memory pointed to by p on realloc fail. This commit (hopefully) fixes all these cases by moving to a standard idiom of : p = SMB_REALLOC(p, size) if (!p) { return error; } Where if the realloc returns null due to the realloc failing or size == 0 we *guarentee* that the storage pointed to by p has been freed. This allows me to remove a lot of code that was dealing with the standard (more verbose) method that required a tmp pointer. This is almost always what you want. When a realloc fails you never usually want the old memory, you want to free it and get into your error processing asap. For the 11 remaining cases where we really do need to keep the old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR, which can be used as follows : tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the pointer p, even on size == 0 or realloc fail. All this is done by a hidden extra argument to Realloc(), BOOL free_old_on_error which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR macros (and their array counterparts). It remains to be seen what this will do to our Coverity bug count :-). Jeremy. (This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 782a8c2b89..8b88990e2f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -383,7 +383,7 @@ void add_session_user(const char *user) "too large.\n")); return; } - newlist = (char *)SMB_REALLOC( + newlist = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR( session_userlist, len_session_userlist + PSTRING_LEN ); if( newlist == NULL ) { -- cgit From 1de2983de4ea1a482c294a9ecce8437cc35ff7ee Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Thu, 9 Mar 2006 22:31:37 +0000 Subject: r14112: * fix checks on return code from register_vuid() which could actually fail and we would still return success in the SMBsesssetup reply :-( * Make sure to create the local token for the server_fino struct in reply_spnego_kerberos() so that register_vuid() does not fail. (how did this ever work?) (This used to be commit 8dafa45b97020d1aceb027a85e18401c965bf402) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8b88990e2f..8d33c1deed 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -305,7 +305,7 @@ int register_vuid(auth_serversupplied_info *server_info, DEBUG(1, ("Failed to claim session for vuid=%d\n", vuser->vuid)); invalidate_vuid(vuser->vuid); - return -1; + return UID_FIELD_INVALID; } /* Register a home dir service for this user iff -- cgit From 3895a5a1fcb2c949647fd310b21476aa1db377f2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 May 2006 21:10:00 +0000 Subject: r15583: Add a comment while trying to understand this code (This used to be commit 7945c935bf197afb61286ddeb0e579078362a1fc) --- source3/smbd/password.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 8d33c1deed..230d7f297f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -189,6 +189,11 @@ int register_vuid(auth_serversupplied_info *server_info, vuser->vuid = next_vuid; if (!server_info) { + /* + * This happens in an unfinished NTLMSSP session setup. We + * need to allocate a vuid between the first and second calls + * to NTLMSSP. + */ next_vuid++; num_validated_vuids++; -- cgit From ee7b4b47cb590dc16ebdf3a40b360b0f0600aa84 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 May 2006 23:05:53 +0000 Subject: r15589: While trying to understand the vuid code I found that security=share is broken right now. r14112 broke it, in 3.0.22 register_vuid for security=share returns UID_FIELD_INVALID which in current 3_0 is turned into an error condition. This makes sure that we only call register_vuid if sec!=share and meanwhile also fixes a little memleak. Then I also found a crash in smbclient with sec=share and hostmsdfs=yes. There's another crash with sec=share when coming from w2k3, but I need sleep now. Someone (jerry,jra?) please review the sesssetup.c change. Thanks, Volker (This used to be commit 8059d0ae395604503cad3d9f197928305923e3f5) --- source3/smbd/password.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 230d7f297f..73b0ebb4b3 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -155,10 +155,9 @@ int register_vuid(auth_serversupplied_info *server_info, { user_struct *vuser = NULL; - /* Ensure no vuid gets registered in share level security. */ + /* Paranoia check. */ if(lp_security() == SEC_SHARE) { - data_blob_free(&session_key); - return UID_FIELD_INVALID; + smb_panic("Tried to register uid in security=share\n"); } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ -- cgit From fbdcf2663b56007a438ac4f0d8d82436b1bfe688 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 11 Jul 2006 18:01:26 +0000 Subject: r16945: Sync trunk -> 3.0 for 3.0.24 code. Still need to do the upper layer directories but this is what everyone is waiting for.... Jeremy. (This used to be commit 9dafb7f48ca3e7af956b0a7d1720c2546fc4cfb8) --- source3/smbd/password.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 73b0ebb4b3..389086e9bf 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -29,9 +29,6 @@ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; static int num_validated_vuids; -extern userdom_struct current_user_info; - - /**************************************************************************** Check if a uid has been validated, and return an pointer to the user_struct if it has. NULL if not. vuid is biased by an offset. This allows us to @@ -550,9 +547,11 @@ static BOOL user_ok(const char *user, int snum) str_list_copy(&invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { - if ( invalid && - str_list_sub_basic(invalid, - current_user_info.smb_name) ) { + + /* This is used in sec=share only, so no current user + * around to pass to str_list_sub_basic() */ + + if ( invalid && str_list_sub_basic(invalid, "", "") ) { ret = !user_in_list(user, (const char **)invalid); } @@ -565,9 +564,11 @@ static BOOL user_ok(const char *user, int snum) str_list_copy(&valid, lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { - if ( valid && - str_list_sub_basic(valid, - current_user_info.smb_name) ) { + + /* This is used in sec=share only, so no current user + * around to pass to str_list_sub_basic() */ + + if ( valid && str_list_sub_basic(valid, "", "") ) { ret = user_in_list(user, (const char **)valid); } } -- cgit From ab75c563704fa86c409072bf1b0938e005aff5ca Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Fri, 4 Aug 2006 22:18:02 +0000 Subject: r17408: Let us use netgroups even without a NIS domain but just using files (This used to be commit c065341d3ffc9125514f563c63d416cf7c40375f) --- source3/smbd/password.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 389086e9bf..38000e93f4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -417,12 +417,11 @@ BOOL user_in_netgroup(const char *user, const char *ngname) yp_get_default_domain(&mydomain); if(mydomain == NULL) { - DEBUG(5,("Unable to get default yp domain\n")); - return False; + DEBUG(5,("Unable to get default yp domain, let's try without specifying it\n")); } DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - user, mydomain, ngname)); + user, mydomain?mydomain:"(ANY)", ngname)); if (innetgr(ngname, NULL, user, mydomain)) { DEBUG(5,("user_in_netgroup: Found\n")); @@ -438,7 +437,7 @@ BOOL user_in_netgroup(const char *user, const char *ngname) strlower_m(lowercase_user); DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", - lowercase_user, mydomain, ngname)); + lowercase_user, mydomain?mydomain:"(ANY)", ngname)); if (innetgr(ngname, NULL, lowercase_user, mydomain)) { DEBUG(5,("user_in_netgroup: Found\n")); -- cgit From 685ca94ac24842fddf22e31edc39de40b0729248 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Feb 2007 22:02:42 +0000 Subject: r21128: Fix Vista connecting to Samba in share level security. Vista sends the NTLMv2 blob by default in the tconX packet. Make sure we save off the workgroup the user was logged into on the client in the sessionsetupX and re-use it for the NTLMv2 calc. Jeremy. (This used to be commit 45dcf62960c2815c4d8e0c5f4a2d0af24df83290) --- source3/smbd/password.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 38000e93f4..10cb920237 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -23,6 +23,8 @@ /* users from session setup */ static char *session_userlist = NULL; static int len_session_userlist = 0; +/* workgroup from session setup. */ +static char *session_workgroup = NULL; /* this holds info on user ids that are already validated for this VC */ static user_struct *validated_users; @@ -402,6 +404,29 @@ void add_session_user(const char *user) safe_strcat(session_userlist,suser,len_session_userlist-1); } +/**************************************************************************** + In security=share mode we need to store the client workgroup, as that's + what Vista uses for the NTLMv2 calculation. +****************************************************************************/ + +void add_session_workgroup(const char *workgroup) +{ + if (session_workgroup) { + SAFE_FREE(session_workgroup); + } + session_workgroup = smb_xstrdup(workgroup); +} + +/**************************************************************************** + In security=share mode we need to return the client workgroup, as that's + what Vista uses for the NTLMv2 calculation. +****************************************************************************/ + +const char *get_session_workgroup(void) +{ + return session_workgroup; +} + /**************************************************************************** Check if a user is in a netgroup user list. If at first we don't succeed, try lower case. -- cgit From f77bdcf6c71a9d0274d96298b136300d5bb05bb1 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 20 Feb 2007 06:22:20 +0000 Subject: r21460: Fix for server-side processing of SPNEGO auth fragmented into "max xmit" size security blob chunks. Bug #4400. Needs limits adding, and also a client-side version. Jeremy. (This used to be commit aa69f2481aafee5dccc3783b8a6e23ca4eb0dbfa) --- source3/smbd/password.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 10cb920237..bf4e9258ff 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -111,6 +111,7 @@ void invalidate_vuid(uint16 vuid) SAFE_FREE(vuser->groups); TALLOC_FREE(vuser->nt_user_token); + SAFE_FREE(vuser); num_validated_vuids--; } -- cgit From fb3835846ef89a632230ff808259dad1cddc05c0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 2 Apr 2007 03:46:13 +0000 Subject: r22020: Make it more clear that both the vuser struct and it's contents are talloc_free()'ed at the end of a session. Rework the passwd cache code to use talloc_unlink and talloc_reference, to more carefully manage the cache. Andrew Bartlett (This used to be commit e3e0ec25e67308de314aa61852905ee42aa2c8fe) --- source3/smbd/password.c | 64 +++++++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 39 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index bf4e9258ff..b7945bd7ea 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -92,14 +92,7 @@ void invalidate_vuid(uint16 vuid) if (vuser == NULL) return; - SAFE_FREE(vuser->homedir); - SAFE_FREE(vuser->unix_homedir); - SAFE_FREE(vuser->logon_script); - session_yield(vuser); - SAFE_FREE(vuser->session_keystr); - - TALLOC_FREE(vuser->server_info); data_blob_free(&vuser->session_key); @@ -109,10 +102,7 @@ void invalidate_vuid(uint16 vuid) from the vuid 'owner' of connections */ conn_clear_vuid_cache(vuid); - SAFE_FREE(vuser->groups); - TALLOC_FREE(vuser->nt_user_token); - - SAFE_FREE(vuser); + TALLOC_FREE(vuser); num_validated_vuids--; } @@ -153,7 +143,7 @@ int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name) { - user_struct *vuser = NULL; + user_struct *vuser; /* Paranoia check. */ if(lp_security() == SEC_SHARE) { @@ -166,14 +156,12 @@ int register_vuid(auth_serversupplied_info *server_info, return UID_FIELD_INVALID; } - if((vuser = SMB_MALLOC_P(user_struct)) == NULL) { - DEBUG(0,("Failed to malloc users struct!\n")); + if((vuser = talloc_zero(NULL, user_struct)) == NULL) { + DEBUG(0,("Failed to talloc users struct!\n")); data_blob_free(&session_key); return UID_FIELD_INVALID; } - ZERO_STRUCTP(vuser); - /* Allocate a free vuid. Yes this is a linear search... :-) */ while( get_valid_user_struct(next_vuid) != NULL ) { next_vuid++; @@ -203,6 +191,11 @@ int register_vuid(auth_serversupplied_info *server_info, return vuser->vuid; } + /* use this to keep tabs on all our info from the authentication */ + vuser->server_info = server_info; + /* Ensure that the server_info will dissapear with the vuser it is now attached to */ + talloc_steal(vuser, vuser->server_info); + /* the next functions should be done by a SID mapping system (SMS) as * the new real sam db won't have reference to unix uids or gids */ @@ -212,14 +205,13 @@ int register_vuid(auth_serversupplied_info *server_info, vuser->n_groups = server_info->n_groups; if (vuser->n_groups) { - if (!(vuser->groups = (gid_t *)memdup(server_info->groups, - sizeof(gid_t) * - vuser->n_groups))) { - DEBUG(0,("register_vuid: failed to memdup " + if (!(vuser->groups = (gid_t *)talloc_memdup(vuser, server_info->groups, + sizeof(gid_t) * + vuser->n_groups))) { + DEBUG(0,("register_vuid: failed to talloc_memdup " "vuser->groups\n")); data_blob_free(&session_key); - free(vuser); - TALLOC_FREE(server_info); + TALLOC_FREE(vuser); return UID_FIELD_INVALID; } } @@ -247,24 +239,26 @@ int register_vuid(auth_serversupplied_info *server_info, const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); if (unix_homedir) { - vuser->unix_homedir = - smb_xstrdup(unix_homedir); + vuser->unix_homedir = unix_homedir; } } else { struct passwd *passwd = - getpwnam_alloc(NULL, vuser->user.unix_name); + getpwnam_alloc(vuser, vuser->user.unix_name); if (passwd) { - vuser->unix_homedir = - smb_xstrdup(passwd->pw_dir); + vuser->unix_homedir = passwd->pw_dir; + /* Ensure that the unix_homedir now + * belongs to vuser, so it goes away + * with it, not with passwd below: */ + talloc_steal(vuser, vuser->unix_homedir); TALLOC_FREE(passwd); } } if (homedir) { - vuser->homedir = smb_xstrdup(homedir); + vuser->homedir = homedir; } if (logon_script) { - vuser->logon_script = smb_xstrdup(logon_script); + vuser->logon_script = logon_script; } } @@ -280,23 +274,15 @@ int register_vuid(auth_serversupplied_info *server_info, vuser->user.full_name)); if (server_info->ptok) { - vuser->nt_user_token = dup_nt_token(NULL, server_info->ptok); + vuser->nt_user_token = dup_nt_token(vuser, server_info->ptok); } else { DEBUG(1, ("server_info does not contain a user_token - " "cannot continue\n")); - TALLOC_FREE(server_info); + TALLOC_FREE(vuser); data_blob_free(&session_key); - SAFE_FREE(vuser->homedir); - SAFE_FREE(vuser->unix_homedir); - SAFE_FREE(vuser->logon_script); - - SAFE_FREE(vuser); return UID_FIELD_INVALID; } - /* use this to keep tabs on all our info from the authentication */ - vuser->server_info = server_info; - DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n", (int)vuser->uid,vuser->user.unix_name, vuser->vuid)); -- cgit From 12ba88574bf91bdcc4447bfc3d429b799064bfd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Apr 2007 23:18:41 +0000 Subject: r22542: Move over to using the _strict varients of the talloc calls. No functional changes. Looks bigger than it is :-). Jeremy. (This used to be commit f6fa3080fee1b20df9f1968500840a88cf0ee592) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b7945bd7ea..ce03e6d85f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -156,7 +156,7 @@ int register_vuid(auth_serversupplied_info *server_info, return UID_FIELD_INVALID; } - if((vuser = talloc_zero(NULL, user_struct)) == NULL) { + if((vuser = TALLOC_ZERO_P(NULL, user_struct)) == NULL) { DEBUG(0,("Failed to talloc users struct!\n")); data_blob_free(&session_key); return UID_FIELD_INVALID; -- cgit From b1ce226af8b61ad7e3c37860a59c6715012e738b Mon Sep 17 00:00:00 2001 From: James Peach Date: Fri, 15 Jun 2007 21:58:49 +0000 Subject: r23510: Tidy calls to smb_panic by removing trailing newlines. Print the failed expression in SMB_ASSERT. (This used to be commit 171dc060e2a576d724eed1ca65636bdafffd7713) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ce03e6d85f..00f687dc27 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -147,7 +147,7 @@ int register_vuid(auth_serversupplied_info *server_info, /* Paranoia check. */ if(lp_security() == SEC_SHARE) { - smb_panic("Tried to register uid in security=share\n"); + smb_panic("Tried to register uid in security=share"); } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 00f687dc27..f9654ce3a4 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/smbd/password.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index f9654ce3a4..1a7dc33c61 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 57e2718e097bba57c96632064956f6ce048d8f28 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Aug 2007 01:43:22 +0000 Subject: r24589: Refactor our vuid code so that we keep the same vuid that was allocated whilst the connection is being constructed and after the connection has been set up. This is what Windows does and at least one client (and HP printer) depends on this behaviour. As it depends on the req struct not yet ported to SAMBA_3_2_0 (Volker, hint hint.... :-) I am not yet adding this to that branch, but will investigate that tomorrow. Jeremy. (This used to be commit a54f2805df92c67e74a6764568eedebe394fd500) --- source3/smbd/password.c | 297 +++++++++++++++++++++++++++--------------------- 1 file changed, 165 insertions(+), 132 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 1a7dc33c61..847b8db082 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -30,13 +30,12 @@ static user_struct *validated_users; static int next_vuid = VUID_OFFSET; static int num_validated_vuids; -/**************************************************************************** - Check if a uid has been validated, and return an pointer to the user_struct - if it has. NULL if not. vuid is biased by an offset. This allows us to - tell random client vuid's (normally zero) from valid vuids. -****************************************************************************/ +enum server_allocated_state { SERVER_ALLOCATED_REQUIRED_YES, + SERVER_ALLOCATED_REQUIRED_NO, + SERVER_ALLOCATED_REQUIRED_ANY}; -user_struct *get_valid_user_struct(uint16 vuid) +static user_struct *get_valid_user_struct_internal(uint16 vuid, + enum server_allocated_state server_allocated) { user_struct *usp; int count=0; @@ -45,7 +44,20 @@ user_struct *get_valid_user_struct(uint16 vuid) return NULL; for (usp=validated_users;usp;usp=usp->next,count++) { - if (vuid == usp->vuid && usp->server_info) { + if (vuid == usp->vuid) { + switch (server_allocated) { + case SERVER_ALLOCATED_REQUIRED_YES: + if (usp->server_info == NULL) { + continue; + } + break; + case SERVER_ALLOCATED_REQUIRED_NO: + if (usp->server_info != NULL) { + continue; + } + case SERVER_ALLOCATED_REQUIRED_ANY: + break; + } if (count > 10) { DLIST_PROMOTE(validated_users, usp); } @@ -57,27 +69,33 @@ user_struct *get_valid_user_struct(uint16 vuid) } /**************************************************************************** - Get the user struct of a partial NTLMSSP login + Check if a uid has been validated, and return an pointer to the user_struct + if it has. NULL if not. vuid is biased by an offset. This allows us to + tell random client vuid's (normally zero) from valid vuids. ****************************************************************************/ -user_struct *get_partial_auth_user_struct(uint16 vuid) +user_struct *get_valid_user_struct(uint16 vuid) { - user_struct *usp; - int count=0; - - if (vuid == UID_FIELD_INVALID) - return NULL; + return get_valid_user_struct_internal(vuid, SERVER_ALLOCATED_REQUIRED_YES); +} - for (usp=validated_users;usp;usp=usp->next,count++) { - if (vuid == usp->vuid && !usp->server_info) { - if (count > 10) { - DLIST_PROMOTE(validated_users, usp); - } - return usp; - } +BOOL is_partial_auth_vuid(uint16 vuid) +{ + if (vuid == UID_FIELD_INVALID) { + return False; } + return get_valid_user_struct_internal(vuid, + SERVER_ALLOCATED_REQUIRED_NO) ? True : False; +} - return NULL; +/**************************************************************************** + Get the user struct of a partial NTLMSSP login +****************************************************************************/ + +user_struct *get_partial_auth_user_struct(uint16 vuid) +{ + return get_valid_user_struct_internal(vuid, + SERVER_ALLOCATED_REQUIRED_NO); } /**************************************************************************** @@ -86,11 +104,18 @@ user_struct *get_partial_auth_user_struct(uint16 vuid) void invalidate_vuid(uint16 vuid) { - user_struct *vuser = get_valid_user_struct(vuid); + user_struct *vuser = NULL; - if (vuser == NULL) + if (vuid == UID_FIELD_INVALID) { return; - + } + + vuser = get_valid_user_struct_internal(vuid, + SERVER_ALLOCATED_REQUIRED_ANY); + if (vuser == NULL) { + return; + } + session_yield(vuser); data_blob_free(&vuser->session_key); @@ -115,116 +140,127 @@ void invalidate_all_vuids(void) for (usp=validated_users;usp;usp=next) { next = usp->next; - invalidate_vuid(usp->vuid); } } -/** - * register that a valid login has been performed, establish 'session'. - * @param server_info The token returned from the authentication process. - * (now 'owned' by register_vuid) - * - * @param session_key The User session key for the login session (now also - * 'owned' by register_vuid) - * - * @param respose_blob The NT challenge-response, if available. (May be - * freed after this call) - * - * @param smb_name The untranslated name of the user - * - * @return Newly allocated vuid, biased by an offset. (This allows us to - * tell random client vuid's (normally zero) from valid vuids.) - * - */ +/**************************************************** + Create a new partial auth user struct. +*****************************************************/ -int register_vuid(auth_serversupplied_info *server_info, - DATA_BLOB session_key, DATA_BLOB response_blob, - const char *smb_name) +int register_initial_vuid(void) { user_struct *vuser; /* Paranoia check. */ if(lp_security() == SEC_SHARE) { - smb_panic("Tried to register uid in security=share"); + smb_panic("register_initial_vuid: " + "Tried to register uid in security=share"); } /* Limit allowed vuids to 16bits - VUID_OFFSET. */ if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) { - data_blob_free(&session_key); return UID_FIELD_INVALID; } - if((vuser = TALLOC_ZERO_P(NULL, user_struct)) == NULL) { - DEBUG(0,("Failed to talloc users struct!\n")); - data_blob_free(&session_key); + if((vuser = talloc_zero(NULL, user_struct)) == NULL) { + DEBUG(0,("register_initial_vuid: " + "Failed to talloc users struct!\n")); return UID_FIELD_INVALID; } - /* Allocate a free vuid. Yes this is a linear search... :-) */ - while( get_valid_user_struct(next_vuid) != NULL ) { + /* Allocate a free vuid. Yes this is a linear search... */ + while( get_valid_user_struct_internal(next_vuid, + SERVER_ALLOCATED_REQUIRED_ANY) != NULL ) { next_vuid++; /* Check for vuid wrap. */ - if (next_vuid == UID_FIELD_INVALID) + if (next_vuid == UID_FIELD_INVALID) { next_vuid = VUID_OFFSET; + } } - DEBUG(10,("register_vuid: allocated vuid = %u\n", - (unsigned int)next_vuid )); + DEBUG(10,("register_initial_vuid: allocated vuid = %u\n", + (unsigned int)next_vuid )); vuser->vuid = next_vuid; - if (!server_info) { - /* - * This happens in an unfinished NTLMSSP session setup. We - * need to allocate a vuid between the first and second calls - * to NTLMSSP. - */ - next_vuid++; - num_validated_vuids++; - - vuser->server_info = NULL; - - DLIST_ADD(validated_users, vuser); - - return vuser->vuid; + /* + * This happens in an unfinished NTLMSSP session setup. We + * need to allocate a vuid between the first and second calls + * to NTLMSSP. + */ + next_vuid++; + num_validated_vuids++; + + DLIST_ADD(validated_users, vuser); + return vuser->vuid; +} + +/** + * register that a valid login has been performed, establish 'session'. + * @param server_info The token returned from the authentication process. + * (now 'owned' by register_existing_vuid) + * + * @param session_key The User session key for the login session (now also + * 'owned' by register_existing_vuid) + * + * @param respose_blob The NT challenge-response, if available. (May be + * freed after this call) + * + * @param smb_name The untranslated name of the user + * + * @return Newly allocated vuid, biased by an offset. (This allows us to + * tell random client vuid's (normally zero) from valid vuids.) + * + */ + +int register_existing_vuid(uint16 vuid, + auth_serversupplied_info *server_info, + DATA_BLOB session_key, + DATA_BLOB response_blob, + const char *smb_name) +{ + user_struct *vuser = get_partial_auth_user_struct(vuid); + if (!vuser) { + goto fail; } - /* use this to keep tabs on all our info from the authentication */ + /* Use this to keep tabs on all our info from the authentication */ vuser->server_info = server_info; - /* Ensure that the server_info will dissapear with the vuser it is now attached to */ + + /* Ensure that the server_info will disappear with + * the vuser it is now attached to */ + talloc_steal(vuser, vuser->server_info); /* the next functions should be done by a SID mapping system (SMS) as * the new real sam db won't have reference to unix uids or gids */ - + vuser->uid = server_info->uid; vuser->gid = server_info->gid; - + vuser->n_groups = server_info->n_groups; if (vuser->n_groups) { - if (!(vuser->groups = (gid_t *)talloc_memdup(vuser, server_info->groups, - sizeof(gid_t) * - vuser->n_groups))) { - DEBUG(0,("register_vuid: failed to talloc_memdup " - "vuser->groups\n")); - data_blob_free(&session_key); - TALLOC_FREE(vuser); - return UID_FIELD_INVALID; + if (!(vuser->groups = (gid_t *)talloc_memdup(vuser, + server_info->groups, + sizeof(gid_t)*vuser->n_groups))) { + DEBUG(0,("register_existing_vuid: " + "failed to talloc_memdup vuser->groups\n")); + goto fail; } } vuser->guest = server_info->guest; - fstrcpy(vuser->user.unix_name, server_info->unix_name); + fstrcpy(vuser->user.unix_name, server_info->unix_name); /* This is a potentially untrusted username */ alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", - sizeof(vuser->user.smb_name)); + sizeof(vuser->user.smb_name)); fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); fstrcpy(vuser->user.full_name, - pdb_get_fullname(server_info->sam_account)); + pdb_get_fullname(server_info->sam_account)); { /* Keep the homedir handy */ @@ -234,7 +270,7 @@ int register_vuid(auth_serversupplied_info *server_info, pdb_get_logon_script(server_info->sam_account); if (!IS_SAM_DEFAULT(server_info->sam_account, - PDB_UNIXHOMEDIR)) { + PDB_UNIXHOMEDIR)) { const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account); if (unix_homedir) { @@ -252,7 +288,7 @@ int register_vuid(auth_serversupplied_info *server_info, TALLOC_FREE(passwd); } } - + if (homedir) { vuser->homedir = homedir; } @@ -260,86 +296,83 @@ int register_vuid(auth_serversupplied_info *server_info, vuser->logon_script = logon_script; } } - vuser->session_key = session_key; - DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", - (unsigned int)vuser->uid, - (unsigned int)vuser->gid, - vuser->user.unix_name, vuser->user.smb_name, - vuser->user.domain, vuser->guest )); + DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", + (unsigned int)vuser->uid, + (unsigned int)vuser->gid, + vuser->user.unix_name, vuser->user.smb_name, + vuser->user.domain, vuser->guest )); - DEBUG(3, ("User name: %s\tReal name: %s\n", vuser->user.unix_name, - vuser->user.full_name)); + DEBUG(3, ("register_existing_vuid: User name: %s\t" + "Real name: %s\n", vuser->user.unix_name, + vuser->user.full_name)); - if (server_info->ptok) { + if (server_info->ptok) { vuser->nt_user_token = dup_nt_token(vuser, server_info->ptok); } else { - DEBUG(1, ("server_info does not contain a user_token - " - "cannot continue\n")); - TALLOC_FREE(vuser); - data_blob_free(&session_key); - return UID_FIELD_INVALID; + DEBUG(1, ("register_existing_vuid: server_info does not " + "contain a user_token - cannot continue\n")); + goto fail; } - DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n", - (int)vuser->uid,vuser->user.unix_name, vuser->vuid)); + DEBUG(3,("register_existing_vuid: UNIX uid %d is UNIX user %s, " + "and will be vuid %u\n", + (int)vuser->uid,vuser->user.unix_name, vuser->vuid)); next_vuid++; num_validated_vuids++; - DLIST_ADD(validated_users, vuser); - if (!session_claim(vuser)) { - DEBUG(1, ("Failed to claim session for vuid=%d\n", - vuser->vuid)); - invalidate_vuid(vuser->vuid); - return UID_FIELD_INVALID; + DEBUG(1, ("register_existing_vuid: Failed to claim session " + "for vuid=%d\n", + vuser->vuid)); + goto fail; } - /* Register a home dir service for this user iff - - (a) This is not a guest connection, - (b) we have a home directory defined - (c) there s not an existing static share by that name - - If a share exists by this name (autoloaded or not) reuse it . */ + /* Register a home dir service for this user if + (a) This is not a guest connection, + (b) we have a home directory defined + (c) there s not an existing static share by that name + If a share exists by this name (autoloaded or not) reuse it . */ vuser->homes_snum = -1; - - if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) - { + if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { int servicenumber = lp_servicenumber(vuser->user.unix_name); - if ( servicenumber == -1 ) { DEBUG(3, ("Adding homes service for user '%s' using " - "home directory: '%s'\n", + "home directory: '%s'\n", vuser->user.unix_name, vuser->unix_homedir)); vuser->homes_snum = - add_home_service(vuser->user.unix_name, - vuser->user.unix_name, - vuser->unix_homedir); + add_home_service(vuser->user.unix_name, + vuser->user.unix_name, + vuser->unix_homedir); } else { DEBUG(3, ("Using static (or previously created) " - "service for user '%s'; path = '%s'\n", - vuser->user.unix_name, - lp_pathname(servicenumber) )); + "service for user '%s'; path = '%s'\n", + vuser->user.unix_name, + lp_pathname(servicenumber) )); vuser->homes_snum = servicenumber; } - } - + } + if (srv_is_signing_negotiated() && !vuser->guest && - !srv_signing_started()) { + !srv_signing_started()) { /* Try and turn on server signing on the first non-guest * sessionsetup. */ srv_set_signing(vuser->session_key, response_blob); } - + /* fill in the current_user_info struct */ set_current_user_info( &vuser->user ); + return vuser->vuid; + fail: - return vuser->vuid; + if (vuser) { + invalidate_vuid(vuid); + } + return UID_FIELD_INVALID; } /**************************************************************************** -- cgit From 644b43d993db7ec709a2bc4e121426e7a27237e8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 21 Aug 2007 02:04:24 +0000 Subject: r24590: Reformatting to coding standards. Added my (C) in places it already should have been :-). Jeremy. (This used to be commit 41611a22ed852bb74e2ef3f45766c0580ffd3a18) --- source3/smbd/password.c | 41 ++++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 19 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 847b8db082..a1590f2a58 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1,18 +1,19 @@ -/* +/* Unix SMB/CIFS implementation. Password and authentication handling Copyright (C) Andrew Tridgell 1992-1998 - + Copyright (C) Jeremy Allison 2007. + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -76,7 +77,8 @@ static user_struct *get_valid_user_struct_internal(uint16 vuid, user_struct *get_valid_user_struct(uint16 vuid) { - return get_valid_user_struct_internal(vuid, SERVER_ALLOCATED_REQUIRED_YES); + return get_valid_user_struct_internal(vuid, + SERVER_ALLOCATED_REQUIRED_YES); } BOOL is_partial_auth_vuid(uint16 vuid) @@ -461,7 +463,8 @@ BOOL user_in_netgroup(const char *user, const char *ngname) yp_get_default_domain(&mydomain); if(mydomain == NULL) { - DEBUG(5,("Unable to get default yp domain, let's try without specifying it\n")); + DEBUG(5,("Unable to get default yp domain, " + "let's try without specifying it\n")); } DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", @@ -479,7 +482,7 @@ BOOL user_in_netgroup(const char *user, const char *ngname) fstrcpy(lowercase_user, user); strlower_m(lowercase_user); - + DEBUG(5,("looking for user %s of domain %s in netgroup %s\n", lowercase_user, mydomain?mydomain:"(ANY)", ngname)); @@ -568,7 +571,7 @@ BOOL user_in_list(const char *user,const char **list) return True; } } - + list++; } return(False); @@ -654,7 +657,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) endnetgrent(); } #endif - + #ifdef HAVE_GETGRENT { struct group *gptr; @@ -727,26 +730,26 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ -BOOL authorise_login(int snum, fstring user, DATA_BLOB password, +BOOL authorise_login(int snum, fstring user, DATA_BLOB password, BOOL *guest) { BOOL ok = False; - + #ifdef DEBUG_PASSWORD DEBUG(100,("authorise_login: checking authorisation on " "user=%s pass=%s\n", user,password.data)); #endif *guest = False; - + /* there are several possibilities: 1) login as the given user with given password - 2) login as a previously registered username with the given + 2) login as a previously registered username with the given password 3) login as a session list username with the given password 4) login as a previously validated user/password pair 5) login as the "user =" user with given password - 6) login as the "user =" user with no password + 6) login as the "user =" user with no password (guest connection) 7) login as guest user with no password @@ -765,14 +768,14 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, if (!user_list) return(False); - + for (auser=strtok(user_list,LIST_SEP); !ok && auser; auser = strtok(NULL,LIST_SEP)) { fstring user2; fstrcpy(user2,auser); if (!user_ok(user2,snum)) continue; - + if (password_ok(user2,password)) { ok = True; fstrcpy(user,user2); @@ -784,15 +787,15 @@ BOOL authorise_login(int snum, fstring user, DATA_BLOB password, SAFE_FREE(user_list); } - + /* check the user= fields and the given password */ if (!ok && lp_username(snum)) { char *auser; pstring user_list; pstrcpy(user_list,lp_username(snum)); - + pstring_sub(user_list,"%S",lp_servicename(snum)); - + for (auser=strtok(user_list,LIST_SEP); auser && !ok; auser = strtok(NULL,LIST_SEP)) { if (*auser == '@') { -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/smbd/password.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a1590f2a58..995abbf663 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -81,7 +81,7 @@ user_struct *get_valid_user_struct(uint16 vuid) SERVER_ALLOCATED_REQUIRED_YES); } -BOOL is_partial_auth_vuid(uint16 vuid) +bool is_partial_auth_vuid(uint16 vuid) { if (vuid == UID_FIELD_INVALID) { return False; @@ -453,7 +453,7 @@ const char *get_session_workgroup(void) try lower case. ****************************************************************************/ -BOOL user_in_netgroup(const char *user, const char *ngname) +bool user_in_netgroup(const char *user, const char *ngname) { #ifdef HAVE_NETGROUP static char *mydomain = NULL; @@ -500,7 +500,7 @@ BOOL user_in_netgroup(const char *user, const char *ngname) and netgroup lists. ****************************************************************************/ -BOOL user_in_list(const char *user,const char **list) +bool user_in_list(const char *user,const char **list) { if (!list || !*list) return False; @@ -581,10 +581,10 @@ BOOL user_in_list(const char *user,const char **list) Check if a username is valid. ****************************************************************************/ -static BOOL user_ok(const char *user, int snum) +static bool user_ok(const char *user, int snum) { char **valid, **invalid; - BOOL ret; + bool ret; valid = invalid = NULL; ret = True; @@ -730,10 +730,10 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) Note this is *NOT* used when logging on using sessionsetup_and_X. ****************************************************************************/ -BOOL authorise_login(int snum, fstring user, DATA_BLOB password, - BOOL *guest) +bool authorise_login(int snum, fstring user, DATA_BLOB password, + bool *guest) { - BOOL ok = False; + bool ok = False; #ifdef DEBUG_PASSWORD DEBUG(100,("authorise_login: checking authorisation on " -- cgit From 052efa9a33d7a9a3b9ae9b038f6b3943c85c4bfc Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 13 Nov 2007 12:51:31 -0800 Subject: Remove last pstring from smbd/*.c Jeremy. (This used to be commit f1680bada913af4eaf5c0d686983018d6c8b3e5f) --- source3/smbd/password.c | 70 +++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 25 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 995abbf663..80b541584d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -669,46 +669,51 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) /* * As user_ok can recurse doing a getgrent(), we must - * copy the member list into a pstring on the stack before + * copy the member list onto the heap before * use. Bug pointed out by leon@eatworms.swmed.edu. */ if (gptr) { - pstring member_list; + char *member_list = NULL; + size_t list_len = 0; char *member; - size_t copied_len = 0; int i; + for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { + list_len += strlen(gptr->gr_mem[i])+1; + } + list_len++; + + member_list = SMB_MALLOC(list_len); + if (!member_list) { + endgrent(); + return NULL; + } + *member_list = '\0'; member = member_list; for(i = 0; gptr->gr_mem && gptr->gr_mem[i]; i++) { size_t member_len = strlen(gptr->gr_mem[i])+1; - if(copied_len+member_len < sizeof(pstring)) { - - DEBUG(10,("validate_group: = gr_mem = " - "%s\n", gptr->gr_mem[i])); - - safe_strcpy(member, gptr->gr_mem[i], - sizeof(pstring) - - copied_len - 1); - copied_len += member_len; - member += copied_len; - } else { - *member = '\0'; - } + + DEBUG(10,("validate_group: = gr_mem = " + "%s\n", gptr->gr_mem[i])); + + safe_strcpy(member, gptr->gr_mem[i], + list_len - (member-member_list)); + member += member_len; } endgrent(); member = member_list; while (*member) { - static fstring name; - fstrcpy(name,member); - if (user_ok(name,snum) && - password_ok(name,password)) { - endgrent(); - return(&name[0]); + if (user_ok(member,snum) && + password_ok(member,password)) { + char *name = talloc_strdup(talloc_tos(), + member); + SAFE_FREE(member_list); + return name; } DEBUG(10,("validate_group = member = %s\n", @@ -716,6 +721,8 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) member += strlen(member) + 1; } + + SAFE_FREE(member_list); } else { endgrent(); return NULL; @@ -790,11 +797,22 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, /* check the user= fields and the given password */ if (!ok && lp_username(snum)) { + TALLOC_CTX *ctx = talloc_tos(); char *auser; - pstring user_list; - pstrcpy(user_list,lp_username(snum)); + char *user_list = talloc_strdup(ctx, lp_username(snum)); + + if (!user_list) { + goto check_guest; + } - pstring_sub(user_list,"%S",lp_servicename(snum)); + user_list = talloc_string_sub(ctx, + user_list, + "%S", + lp_servicename(snum)); + + if (!user_list) { + goto check_guest; + } for (auser=strtok(user_list,LIST_SEP); auser && !ok; auser = strtok(NULL,LIST_SEP)) { @@ -823,6 +841,8 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, } } + check_guest: + /* check for a normal guest connection */ if (!ok && GUEST_OK(snum)) { fstring guestname; -- cgit From 3f437f681aa130438774cc5f4b8f16d00b43b377 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 16 Nov 2007 00:34:37 +0100 Subject: Fix an implicit cast warning. Michael (This used to be commit 4ab3b23a630e822e3fdf1ab4d08330625b0e4fb6) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 80b541584d..7bba458218 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -684,7 +684,7 @@ static char *validate_group(char *group, DATA_BLOB password,int snum) } list_len++; - member_list = SMB_MALLOC(list_len); + member_list = (char *)SMB_MALLOC(list_len); if (!member_list) { endgrent(); return NULL; -- cgit From f692694b99319ef1f534ea29f001922656402cdf Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 17:25:41 -0800 Subject: Remove PSTRING_LEN from smbd/ nmbd/. Remove pstring from libsmb/clidfs.c except for a nasty hack (that will be removed when pstrings are gone from client/). Jeremy. (This used to be commit cc257b71d13daa47e6f2315d0f07a60eb4aaeca6) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 7bba458218..75f05dea67 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -402,14 +402,14 @@ void add_session_user(const char *user) len_session_userlist) ) { char *newlist; - if (len_session_userlist > 128 * PSTRING_LEN) { + if (len_session_userlist > 128 * 1024) { DEBUG(3,("add_session_user: session userlist already " "too large.\n")); return; } newlist = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR( session_userlist, - len_session_userlist + PSTRING_LEN ); + len_session_userlist + 1024 ); if( newlist == NULL ) { DEBUG(1,("Unable to resize session_userlist\n")); return; @@ -418,7 +418,7 @@ void add_session_user(const char *user) *newlist = '\0'; } session_userlist = newlist; - len_session_userlist += PSTRING_LEN; + len_session_userlist += 1024; } safe_strcat(session_userlist," ",len_session_userlist-1); -- cgit From 2585232054934bc60e1384f2bdb93bc43f75c7da Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 9 Dec 2007 19:03:49 +0100 Subject: Simplify add_session_user (This used to be commit f98082ccf048a2de6fea8d922264879305b3d2c8) --- source3/smbd/password.c | 58 +++++++++++++++++++++---------------------------- 1 file changed, 25 insertions(+), 33 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 75f05dea67..b3005ba082 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -22,7 +22,6 @@ /* users from session setup */ static char *session_userlist = NULL; -static int len_session_userlist = 0; /* workgroup from session setup. */ static char *session_workgroup = NULL; @@ -383,46 +382,39 @@ int register_existing_vuid(uint16 vuid, void add_session_user(const char *user) { - fstring suser; - struct passwd *passwd; + struct passwd *pw; + char *tmp; - if (!(passwd = Get_Pwnam(user))) - return; - - fstrcpy(suser,passwd->pw_name); + pw = Get_Pwnam_alloc(talloc_tos(), user); - if(!*suser) + if (pw == NULL) { return; + } - if( session_userlist && in_list(suser,session_userlist,False) ) - return; + if (session_userlist == NULL) { + session_userlist = SMB_STRDUP(pw->pw_name); + goto done; + } - if( !session_userlist || - (strlen(suser) + strlen(session_userlist) + 2 >= - len_session_userlist) ) { - char *newlist; + if (in_list(pw->pw_name,session_userlist,False) ) { + goto done; + } - if (len_session_userlist > 128 * 1024) { - DEBUG(3,("add_session_user: session userlist already " - "too large.\n")); - return; - } - newlist = (char *)SMB_REALLOC_KEEP_OLD_ON_ERROR( - session_userlist, - len_session_userlist + 1024 ); - if( newlist == NULL ) { - DEBUG(1,("Unable to resize session_userlist\n")); - return; - } - if (!session_userlist) { - *newlist = '\0'; - } - session_userlist = newlist; - len_session_userlist += 1024; + if (strlen(session_userlist) > 128 * 1024) { + DEBUG(3,("add_session_user: session userlist already " + "too large.\n")); + goto done; + } + + if (asprintf(&tmp, "%s %s", session_userlist, pw->pw_name) == -1) { + DEBUG(3, ("asprintf failed\n")); + goto done; } - safe_strcat(session_userlist," ",len_session_userlist-1); - safe_strcat(session_userlist,suser,len_session_userlist-1); + SAFE_FREE(session_userlist); + session_userlist = tmp; + done: + TALLOC_FREE(pw); } /**************************************************************************** -- cgit From e518e19bc0000019f131354f55e9f5b55f6a2c5e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 19 Dec 2007 15:02:59 +0100 Subject: Remove Get_Pwnam and its associated static variable All callers are replaced by Get_Pwnam_alloc (This used to be commit 735f59315497113aebadcf9ad387e3dbfffa284a) --- source3/smbd/password.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index b3005ba082..6b517c3d86 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -837,9 +837,11 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, /* check for a normal guest connection */ if (!ok && GUEST_OK(snum)) { + struct passwd *guest_pw; fstring guestname; fstrcpy(guestname,lp_guestaccount()); - if (Get_Pwnam(guestname)) { + guest_pw = Get_Pwnam_alloc(talloc_tos(), guestname); + if (guest_pw != NULL) { fstrcpy(user,guestname); ok = True; DEBUG(3,("authorise_login: ACCEPTED: guest account " @@ -848,6 +850,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, DEBUG(0,("authorise_login: Invalid guest account " "%s??\n",guestname)); } + TALLOC_FREE(guest_pw); *guest = True; } -- cgit From 587cf54c61c9f1f7bcae431a82035fd942716c32 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 23 Jan 2008 11:04:10 +0100 Subject: strtok -> strtok_r (This used to be commit fd34ce437057bb34cdc37f4b066e424000d36789) --- source3/smbd/password.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6b517c3d86..85e1ccf0a7 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -759,6 +759,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, if (!ok) { char *auser; char *user_list = NULL; + char *saveptr; if ( session_userlist ) user_list = SMB_STRDUP(session_userlist); @@ -768,8 +769,9 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, if (!user_list) return(False); - for (auser=strtok(user_list,LIST_SEP); !ok && auser; - auser = strtok(NULL,LIST_SEP)) { + for (auser = strtok_r(user_list, LIST_SEP, &saveptr); + !ok && auser; + auser = strtok_r(NULL, LIST_SEP, &saveptr)) { fstring user2; fstrcpy(user2,auser); if (!user_ok(user2,snum)) @@ -792,6 +794,7 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, TALLOC_CTX *ctx = talloc_tos(); char *auser; char *user_list = talloc_strdup(ctx, lp_username(snum)); + char *saveptr; if (!user_list) { goto check_guest; @@ -806,8 +809,9 @@ bool authorise_login(int snum, fstring user, DATA_BLOB password, goto check_guest; } - for (auser=strtok(user_list,LIST_SEP); auser && !ok; - auser = strtok(NULL,LIST_SEP)) { + for (auser = strtok_r(user_list, LIST_SEP, &saveptr); + auser && !ok; + auser = strtok_r(NULL, LIST_SEP, &saveptr)) { if (*auser == '@') { auser = validate_group(auser+1,password,snum); if (auser) { -- cgit From 2762b9a97582b9b28fd5985ba8e3d0299126820e Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Feb 2008 20:57:35 +0100 Subject: Always pass a TALLOC_CTX to str_list_make and str_list_copy (This used to be commit e2c9fc4cf5f0ff725330fa44f53782db65fca37e) --- source3/smbd/password.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 85e1ccf0a7..913c3c35da 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -582,7 +582,7 @@ static bool user_ok(const char *user, int snum) ret = True; if (lp_invalid_users(snum)) { - str_list_copy(&invalid, lp_invalid_users(snum)); + str_list_copy(talloc_tos(), &invalid, lp_invalid_users(snum)); if (invalid && str_list_substitute(invalid, "%S", lp_servicename(snum))) { @@ -599,7 +599,7 @@ static bool user_ok(const char *user, int snum) str_list_free (&invalid); if (ret && lp_valid_users(snum)) { - str_list_copy(&valid, lp_valid_users(snum)); + str_list_copy(talloc_tos(), &valid, lp_valid_users(snum)); if ( valid && str_list_substitute(valid, "%S", lp_servicename(snum)) ) { @@ -615,13 +615,14 @@ static bool user_ok(const char *user, int snum) str_list_free (&valid); if (ret && lp_onlyuser(snum)) { - char **user_list = str_list_make (lp_username(snum), NULL); + char **user_list = str_list_make( + talloc_tos(), lp_username(snum), NULL); if (user_list && str_list_substitute(user_list, "%S", lp_servicename(snum))) { ret = user_in_list(user, (const char **)user_list); } - if (user_list) str_list_free (&user_list); + TALLOC_FREE(user_list); } return(ret); -- cgit From b361956942618ec2f7c2efc60cb190858adbc516 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 4 Feb 2008 21:05:41 +0100 Subject: str_list_free is not needed anymore (This used to be commit feddc1447d585fd108d22a36bccc576fa81197ef) --- source3/smbd/password.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 913c3c35da..687b67950a 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -595,8 +595,7 @@ static bool user_ok(const char *user, int snum) } } } - if (invalid) - str_list_free (&invalid); + TALLOC_FREE(invalid); if (ret && lp_valid_users(snum)) { str_list_copy(talloc_tos(), &valid, lp_valid_users(snum)); @@ -611,8 +610,7 @@ static bool user_ok(const char *user, int snum) } } } - if (valid) - str_list_free (&valid); + TALLOC_FREE(valid); if (ret && lp_onlyuser(snum)) { char **user_list = str_list_make( -- cgit From 0a89940df5255a3921f81721a627610967fe2698 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Feb 2008 18:06:16 -0800 Subject: Ensure invalidate_vuid() deletes any ntlmssp state. Jeremy. (This used to be commit b41799c351c72b268ef094047a51766747671280) --- source3/smbd/password.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 687b67950a..80eba562c5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -121,6 +121,10 @@ void invalidate_vuid(uint16 vuid) data_blob_free(&vuser->session_key); + if (vuser->auth_ntlmssp_state) { + auth_ntlmssp_end(&vuser->auth_ntlmssp_state); + } + DLIST_REMOVE(validated_users, vuser); /* clear the vuid from the 'cache' on each connection, and -- cgit From 1b2bf00fb98417434f653ce869226887d97aaeb2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 12:47:55 +0200 Subject: Remove "homedir" from "struct user_struct" (This used to be commit 41f9afd62d8cc6067582d452f3d53a5c67253b69) --- source3/smbd/password.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 80eba562c5..a7e462a0ca 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -268,9 +268,6 @@ int register_existing_vuid(uint16 vuid, pdb_get_fullname(server_info->sam_account)); { - /* Keep the homedir handy */ - const char *homedir = - pdb_get_homedir(server_info->sam_account); const char *logon_script = pdb_get_logon_script(server_info->sam_account); @@ -294,9 +291,6 @@ int register_existing_vuid(uint16 vuid, } } - if (homedir) { - vuser->homedir = homedir; - } if (logon_script) { vuser->logon_script = logon_script; } -- cgit From 2b3d03d6f16e4110d0000cbb10a087cef2ce9e44 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:23:47 +0200 Subject: Remove unix_homedir from struct user_struct This makes pdb_get_unix_homedir unused. I wonder if that was ever really used... (This used to be commit 36bfd32f1ff878e827db91e9bf233719ecca5b01) --- source3/smbd/password.c | 72 ++++++++++++++++++++++++------------------------- 1 file changed, 35 insertions(+), 37 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a7e462a0ca..74fa645c13 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -201,6 +201,37 @@ int register_initial_vuid(void) return vuser->vuid; } +static int register_homes_share(const char *username) +{ + int result; + struct passwd *pwd; + + result = lp_servicenumber(username); + if (result != -1) { + DEBUG(3, ("Using static (or previously created) service for " + "user '%s'; path = '%s'\n", username, + lp_pathname(result))); + return result; + } + + pwd = getpwnam_alloc(talloc_tos(), username); + + if ((pwd == NULL) || (pwd->pw_dir[0] == '\0')) { + DEBUG(3, ("No home directory defined for user '%s'\n", + username)); + TALLOC_FREE(pwd); + return -1; + } + + DEBUG(3, ("Adding homes service for user '%s' using home directory: " + "'%s'\n", username, pwd->pw_dir)); + + result = add_home_service(username, username, pwd->pw_dir); + + TALLOC_FREE(pwd); + return result; +} + /** * register that a valid login has been performed, establish 'session'. * @param server_info The token returned from the authentication process. @@ -271,26 +302,6 @@ int register_existing_vuid(uint16 vuid, const char *logon_script = pdb_get_logon_script(server_info->sam_account); - if (!IS_SAM_DEFAULT(server_info->sam_account, - PDB_UNIXHOMEDIR)) { - const char *unix_homedir = - pdb_get_unix_homedir(server_info->sam_account); - if (unix_homedir) { - vuser->unix_homedir = unix_homedir; - } - } else { - struct passwd *passwd = - getpwnam_alloc(vuser, vuser->user.unix_name); - if (passwd) { - vuser->unix_homedir = passwd->pw_dir; - /* Ensure that the unix_homedir now - * belongs to vuser, so it goes away - * with it, not with passwd below: */ - talloc_steal(vuser, vuser->unix_homedir); - TALLOC_FREE(passwd); - } - } - if (logon_script) { vuser->logon_script = logon_script; } @@ -336,23 +347,10 @@ int register_existing_vuid(uint16 vuid, If a share exists by this name (autoloaded or not) reuse it . */ vuser->homes_snum = -1; - if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) { - int servicenumber = lp_servicenumber(vuser->user.unix_name); - if ( servicenumber == -1 ) { - DEBUG(3, ("Adding homes service for user '%s' using " - "home directory: '%s'\n", - vuser->user.unix_name, vuser->unix_homedir)); - vuser->homes_snum = - add_home_service(vuser->user.unix_name, - vuser->user.unix_name, - vuser->unix_homedir); - } else { - DEBUG(3, ("Using static (or previously created) " - "service for user '%s'; path = '%s'\n", - vuser->user.unix_name, - lp_pathname(servicenumber) )); - vuser->homes_snum = servicenumber; - } + + if (!vuser->guest) { + vuser->homes_snum = register_homes_share( + vuser->user.unix_name); } if (srv_is_signing_negotiated() && !vuser->guest && -- cgit From faa5e8e12c58376db0323a4e4855454ed53dcc00 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:28:40 +0200 Subject: Remove "logon_script" from "struct user_struct" (This used to be commit b36fd84186a656f86e4cfb9166fc0ecbffb422cb) --- source3/smbd/password.c | 8 -------- 1 file changed, 8 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 74fa645c13..124bc315fa 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -298,14 +298,6 @@ int register_existing_vuid(uint16 vuid, fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); - { - const char *logon_script = - pdb_get_logon_script(server_info->sam_account); - - if (logon_script) { - vuser->logon_script = logon_script; - } - } vuser->session_key = session_key; DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", -- cgit From bb3755968f5e953340edfb0b71997dddc11badb9 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:35:00 +0200 Subject: Remove "nt_user_token" from "struct user_struct" (This used to be commit 51d5d512f28eadc74eced43e5e7f4e5bdff3ff69) --- source3/smbd/password.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 124bc315fa..2636438d5d 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -310,9 +310,7 @@ int register_existing_vuid(uint16 vuid, "Real name: %s\n", vuser->user.unix_name, vuser->user.full_name)); - if (server_info->ptok) { - vuser->nt_user_token = dup_nt_token(vuser, server_info->ptok); - } else { + if (!server_info->ptok) { DEBUG(1, ("register_existing_vuid: server_info does not " "contain a user_token - cannot continue\n")); goto fail; -- cgit From c6d209f8342d56adc52a6c8ab99a4a2e17d409b2 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:43:10 +0200 Subject: Remove the unix token info from "struct user_struct" (This used to be commit aa2299d42adf4d27e707ac755e07be70d0af1bb4) --- source3/smbd/password.c | 26 ++++---------------------- 1 file changed, 4 insertions(+), 22 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 2636438d5d..c5c0245444 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -269,24 +269,6 @@ int register_existing_vuid(uint16 vuid, talloc_steal(vuser, vuser->server_info); - /* the next functions should be done by a SID mapping system (SMS) as - * the new real sam db won't have reference to unix uids or gids - */ - - vuser->uid = server_info->uid; - vuser->gid = server_info->gid; - - vuser->n_groups = server_info->n_groups; - if (vuser->n_groups) { - if (!(vuser->groups = (gid_t *)talloc_memdup(vuser, - server_info->groups, - sizeof(gid_t)*vuser->n_groups))) { - DEBUG(0,("register_existing_vuid: " - "failed to talloc_memdup vuser->groups\n")); - goto fail; - } - } - vuser->guest = server_info->guest; fstrcpy(vuser->user.unix_name, server_info->unix_name); @@ -301,8 +283,8 @@ int register_existing_vuid(uint16 vuid, vuser->session_key = session_key; DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", - (unsigned int)vuser->uid, - (unsigned int)vuser->gid, + (unsigned int)vuser->server_info->uid, + (unsigned int)vuser->server_info->gid, vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, vuser->guest )); @@ -317,8 +299,8 @@ int register_existing_vuid(uint16 vuid, } DEBUG(3,("register_existing_vuid: UNIX uid %d is UNIX user %s, " - "and will be vuid %u\n", - (int)vuser->uid,vuser->user.unix_name, vuser->vuid)); + "and will be vuid %u\n", (int)vuser->server_info->uid, + vuser->user.unix_name, vuser->vuid)); next_vuid++; num_validated_vuids++; -- cgit From 71ff1ba2deddf8fa12b034518e92e0a461871388 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 29 Apr 2008 13:45:58 +0200 Subject: Remove "guest" from "struct user_struct" (This used to be commit 570a6b80feb5b0dc23213ba936c721e766cd4818) --- source3/smbd/password.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index c5c0245444..6305180e6f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -269,7 +269,6 @@ int register_existing_vuid(uint16 vuid, talloc_steal(vuser, vuser->server_info); - vuser->guest = server_info->guest; fstrcpy(vuser->user.unix_name, server_info->unix_name); /* This is a potentially untrusted username */ @@ -286,7 +285,7 @@ int register_existing_vuid(uint16 vuid, (unsigned int)vuser->server_info->uid, (unsigned int)vuser->server_info->gid, vuser->user.unix_name, vuser->user.smb_name, - vuser->user.domain, vuser->guest )); + vuser->user.domain, vuser->server_info->guest )); DEBUG(3, ("register_existing_vuid: User name: %s\t" "Real name: %s\n", vuser->user.unix_name, @@ -320,12 +319,12 @@ int register_existing_vuid(uint16 vuid, vuser->homes_snum = -1; - if (!vuser->guest) { + if (!vuser->server_info->guest) { vuser->homes_snum = register_homes_share( vuser->user.unix_name); } - if (srv_is_signing_negotiated() && !vuser->guest && + if (srv_is_signing_negotiated() && !vuser->server_info->guest && !srv_signing_started()) { /* Try and turn on server signing on the first non-guest * sessionsetup. */ -- cgit From 82d2f07dae5d69fc1635a4ed326a2af6632d8a97 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Apr 2008 14:26:16 +0200 Subject: Remove "session_key" from "struct user_struct" This one took a bit -- I hope I covered all data paths (This used to be commit 74c88a44422f88d6e2f2cdbfdfa0bafe0dbe06c4) --- source3/smbd/password.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 6305180e6f..5e2e713d43 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -119,8 +119,6 @@ void invalidate_vuid(uint16 vuid) session_yield(vuser); - data_blob_free(&vuser->session_key); - if (vuser->auth_ntlmssp_state) { auth_ntlmssp_end(&vuser->auth_ntlmssp_state); } @@ -252,7 +250,6 @@ static int register_homes_share(const char *username) int register_existing_vuid(uint16 vuid, auth_serversupplied_info *server_info, - DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name) { @@ -279,8 +276,6 @@ int register_existing_vuid(uint16 vuid, fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account)); - vuser->session_key = session_key; - DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->server_info->uid, (unsigned int)vuser->server_info->gid, @@ -328,7 +323,7 @@ int register_existing_vuid(uint16 vuid, !srv_signing_started()) { /* Try and turn on server signing on the first non-guest * sessionsetup. */ - srv_set_signing(vuser->session_key, response_blob); + srv_set_signing(vuser->server_info->user_session_key, response_blob); } /* fill in the current_user_info struct */ -- cgit From bec1dfab27be3db888eeb451b4547f16e08e93c3 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 30 Apr 2008 17:42:39 +0200 Subject: Remove "userdom_struct user" from "struct user_struct" (This used to be commit 420de035237bb08bc470c9eb820f3da2edaa6805) --- source3/smbd/password.c | 49 +++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 5e2e713d43..a872ea2b48 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -253,40 +253,36 @@ int register_existing_vuid(uint16 vuid, DATA_BLOB response_blob, const char *smb_name) { - user_struct *vuser = get_partial_auth_user_struct(vuid); + fstring tmp; + user_struct *vuser; + + vuser = get_partial_auth_user_struct(vuid); if (!vuser) { goto fail; } /* Use this to keep tabs on all our info from the authentication */ - vuser->server_info = server_info; - - /* Ensure that the server_info will disappear with - * the vuser it is now attached to */ - - talloc_steal(vuser, vuser->server_info); - - fstrcpy(vuser->user.unix_name, server_info->unix_name); + vuser->server_info = talloc_move(vuser, &server_info); /* This is a potentially untrusted username */ - alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", - sizeof(vuser->user.smb_name)); + alpha_strcpy(tmp, smb_name, ". _-$", sizeof(tmp)); - fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account)); - fstrcpy(vuser->user.full_name, - pdb_get_fullname(server_info->sam_account)); + vuser->server_info->sanitized_username = talloc_strdup( + server_info, tmp); DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", - (unsigned int)vuser->server_info->uid, - (unsigned int)vuser->server_info->gid, - vuser->user.unix_name, vuser->user.smb_name, - vuser->user.domain, vuser->server_info->guest )); + (unsigned int)vuser->server_info->uid, + (unsigned int)vuser->server_info->gid, + vuser->server_info->unix_name, + vuser->server_info->sanitized_username, + pdb_get_domain(vuser->server_info->sam_account), + vuser->server_info->guest )); DEBUG(3, ("register_existing_vuid: User name: %s\t" - "Real name: %s\n", vuser->user.unix_name, - vuser->user.full_name)); + "Real name: %s\n", vuser->server_info->unix_name, + pdb_get_fullname(vuser->server_info->sam_account))); - if (!server_info->ptok) { + if (!vuser->server_info->ptok) { DEBUG(1, ("register_existing_vuid: server_info does not " "contain a user_token - cannot continue\n")); goto fail; @@ -294,7 +290,7 @@ int register_existing_vuid(uint16 vuid, DEBUG(3,("register_existing_vuid: UNIX uid %d is UNIX user %s, " "and will be vuid %u\n", (int)vuser->server_info->uid, - vuser->user.unix_name, vuser->vuid)); + vuser->server_info->unix_name, vuser->vuid)); next_vuid++; num_validated_vuids++; @@ -316,7 +312,7 @@ int register_existing_vuid(uint16 vuid, if (!vuser->server_info->guest) { vuser->homes_snum = register_homes_share( - vuser->user.unix_name); + vuser->server_info->unix_name); } if (srv_is_signing_negotiated() && !vuser->server_info->guest && @@ -327,7 +323,12 @@ int register_existing_vuid(uint16 vuid, } /* fill in the current_user_info struct */ - set_current_user_info( &vuser->user ); + set_current_user_info( + vuser->server_info->sanitized_username, + vuser->server_info->unix_name, + pdb_get_fullname(vuser->server_info->sam_account), + pdb_get_domain(vuser->server_info->sam_account)); + return vuser->vuid; fail: -- cgit From 53802412512f77082f22c279636c9a943afc77eb Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Tue, 6 May 2008 15:41:20 +0200 Subject: Fix a memleak introduced after refactoring "struct user_struct" (This used to be commit e70b5b762234f1733f150bdfbda7b208a8139990) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index a872ea2b48..673a1a01c1 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -268,7 +268,7 @@ int register_existing_vuid(uint16 vuid, alpha_strcpy(tmp, smb_name, ". _-$", sizeof(tmp)); vuser->server_info->sanitized_username = talloc_strdup( - server_info, tmp); + vuser->server_info, tmp); DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", (unsigned int)vuser->server_info->uid, -- cgit From 101162257c14338eb2df7f331b18bca41813bff7 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 14 Jun 2008 16:59:07 +0200 Subject: Move connection-specific vuid cache clear to uid.c (This used to be commit 1025f687910ce40283c7344ed67ebd5bf31217b7) --- source3/smbd/password.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 673a1a01c1..ebc72350b5 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -127,7 +127,7 @@ void invalidate_vuid(uint16 vuid) /* clear the vuid from the 'cache' on each connection, and from the vuid 'owner' of connections */ - conn_clear_vuid_cache(vuid); + conn_clear_vuid_caches(vuid); TALLOC_FREE(vuser); num_validated_vuids--; -- cgit From 40f5eab5eb515937e1b23cf6762b77c194d29b9d Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 19 Jun 2008 16:54:12 +0200 Subject: Wrap the unix token info in a unix_user_token in auth_serversupplied_info No functional change, this is a preparation for more current_user ref removal (This used to be commit dcaedf345e62ab74ea87f0a3fa1e3199c75c5445) --- source3/smbd/password.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/smbd/password.c') diff --git a/source3/smbd/password.c b/source3/smbd/password.c index ebc72350b5..1d3514429f 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -271,8 +271,8 @@ int register_existing_vuid(uint16 vuid, vuser->server_info, tmp); DEBUG(10,("register_existing_vuid: (%u,%u) %s %s %s guest=%d\n", - (unsigned int)vuser->server_info->uid, - (unsigned int)vuser->server_info->gid, + (unsigned int)vuser->server_info->utok.uid, + (unsigned int)vuser->server_info->utok.gid, vuser->server_info->unix_name, vuser->server_info->sanitized_username, pdb_get_domain(vuser->server_info->sam_account), @@ -289,7 +289,7 @@ int register_existing_vuid(uint16 vuid, } DEBUG(3,("register_existing_vuid: UNIX uid %d is UNIX user %s, " - "and will be vuid %u\n", (int)vuser->server_info->uid, + "and will be vuid %u\n", (int)vuser->server_info->utok.uid, vuser->server_info->unix_name, vuser->vuid)); next_vuid++; -- cgit