diff options
-rw-r--r-- | source3/auth/auth_server.c | 21 | ||||
-rw-r--r-- | source3/auth/auth_unix.c | 2 | ||||
-rw-r--r-- | source3/auth/auth_util.c | 137 | ||||
-rw-r--r-- | source3/smbd/sesssetup.c | 12 |
4 files changed, 96 insertions, 76 deletions
diff --git a/source3/auth/auth_server.c b/source3/auth/auth_server.c index 41adc21784..bc611ec229 100644 --- a/source3/auth/auth_server.c +++ b/source3/auth/auth_server.c @@ -377,18 +377,17 @@ use this machine as the password server.\n")); cli_ulogoff(cli); if (NT_STATUS_IS_OK(nt_status)) { - struct passwd *pass = Get_Pwnam(user_info->internal_username.str); - if (pass) { - nt_status = make_server_info_pw(server_info, pass); - } else { - auth_add_user_script(user_info->domain.str, user_info->internal_username.str); - pass = Get_Pwnam(user_info->internal_username.str); + fstring real_username; + struct passwd *pass; - if (pass) { - nt_status = make_server_info_pw(server_info, pass); - } else { - nt_status = NT_STATUS_NO_SUCH_USER; - } + if ( (pass = smb_getpwnam( user_info->internal_username.str, + real_username, True )) != NULL ) + { + nt_status = make_server_info_pw(server_info, pass->pw_name, pass); + } + else + { + nt_status = NT_STATUS_NO_SUCH_USER; } } diff --git a/source3/auth/auth_unix.c b/source3/auth/auth_unix.c index b9de6f7acb..f744cba0c4 100644 --- a/source3/auth/auth_unix.c +++ b/source3/auth/auth_unix.c @@ -108,7 +108,7 @@ static NTSTATUS check_unix_security(const struct auth_context *auth_context, if (NT_STATUS_IS_OK(nt_status)) { if (pass) { - make_server_info_pw(server_info, pass); + make_server_info_pw(server_info, pass->pw_name, pass); } else { /* we need to do somthing more useful here */ nt_status = NT_STATUS_NO_SUCH_USER; diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index 0f945b33cb..dfc3f6cc21 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -757,6 +757,7 @@ Fill a server_info struct from a SAM_ACCOUNT with their groups ***************************************************************************/ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info, + const char * unix_username, SAM_ACCOUNT *sampass, uid_t uid, gid_t gid) { @@ -770,7 +771,7 @@ static NTSTATUS add_user_groups(auth_serversupplied_info **server_info, BOOL is_guest; uint32 rid; - nt_status = get_user_groups(pdb_get_username(sampass), uid, gid, + nt_status = get_user_groups(unix_username, uid, gid, &n_groupSIDs, &groupSIDs, &unix_groups); if (!NT_STATUS_IS_OK(nt_status)) { @@ -828,9 +829,11 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, passwd_free(&pwd); - if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, + if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass), + sampass, (*server_info)->uid, - (*server_info)->gid))) { + (*server_info)->gid))) + { free_server_info(server_info); return nt_status; } @@ -848,7 +851,9 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, to a SAM_ACCOUNT ***************************************************************************/ -NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struct passwd *pwd) +NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, + char *unix_username, + struct passwd *pwd) { NTSTATUS nt_status; SAM_ACCOUNT *sampass = NULL; @@ -861,11 +866,13 @@ NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, const struc (*server_info)->sam_account = sampass; - if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, sampass, pwd->pw_uid, pwd->pw_gid))) { + if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, unix_username, + sampass, pwd->pw_uid, pwd->pw_gid))) + { return nt_status; } - (*server_info)->unix_name = smb_xstrdup(pwd->pw_name); + (*server_info)->unix_name = smb_xstrdup(unix_username); (*server_info)->sam_fill_level = SAM_FILL_ALL; (*server_info)->uid = pwd->pw_uid; @@ -924,52 +931,30 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, SAM_ACCOUNT **sam_account) { fstring dom_user; + fstring real_username; struct passwd *passwd; fstr_sprintf(dom_user, "%s%s%s", domain, lp_winbind_separator(), username); - passwd = Get_Pwnam(dom_user); - - if ( passwd ) { - char *p; - - /* make sure we get the case of the username correct */ - /* work around 'winbind use default domain = yes' */ - - p = strchr( passwd->pw_name, *lp_winbind_separator() ); - if ( !p ) - fstr_sprintf(dom_user, "%s%s%s", domain, - lp_winbind_separator(), passwd->pw_name); - else - fstrcpy( dom_user, passwd->pw_name ); - } - else { - /* if the lookup for DOMAIN\username failed, try again - with just 'username'. This is need for accessing the server - as a trust user that actually maps to a local account */ - - fstrcpy( dom_user, username ); - passwd = Get_Pwnam( dom_user ); - - /* make sure we get the case of the username correct */ - if ( passwd ) - fstrcpy( dom_user, passwd->pw_name ); - } + /* get the passwd struct but don't create the user if he/she + does not exist. We were explicitly called from a following + a winbindd authentication request so we should assume that + nss_winbindd is working */ - if ( !passwd ) + if ( !(passwd = smb_getpwnam( dom_user, real_username, True )) ) return NT_STATUS_NO_SUCH_USER; *uid = passwd->pw_uid; *gid = passwd->pw_gid; - /* This is pointless -- there is no suport for differeing + /* This is pointless -- there is no suport for differing unix and windows names. Make sure to always store the one we actually looked up and succeeded. Have I mentioned why I hate the 'winbind use default domain' parameter? --jerry */ - *found_username = talloc_strdup(mem_ctx, dom_user); + *found_username = talloc_strdup( mem_ctx, real_username ); DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username)); @@ -983,40 +968,72 @@ static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, the username if we fallback to the username only. ****************************************************************************/ -struct passwd *smb_getpwnam( char *domuser ) +struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ) { struct passwd *pw = NULL; char *p; fstring mapped_username; + + /* we only save a copy of the username it has been mangled + by winbindd use default domain */ + + save_username[0] = '\0'; + + /* save a local copy of the username and run it through the + username map */ + + fstrcpy( mapped_username, domuser ); + map_username( mapped_username ); + + p = strchr_m( mapped_username, *lp_winbind_separator() ); + + /* code for a DOMAIN\user string */ + + if ( p ) { + pw = Get_Pwnam( domuser ); + if ( pw ) { + /* make sure we get the case of the username correct */ + /* work around 'winbind use default domain = yes' */ - pw = Get_Pwnam( domuser ); - if ( pw ) - return pw; - - /* fallback to looking up just the username */ + if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { + char *domain; + + domain = mapped_username; + *p = '\0'; + fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name); + } + else + fstrcpy( save_username, pw->pw_name ); - p = strchr( domuser, *lp_winbind_separator() ); + /* whew -- done! */ + return pw; + } - if ( p ) { - p += 1; + /* setup for lookup of just the username */ + p++; fstrcpy( mapped_username, p ); - map_username( mapped_username ); + + } + + /* just lookup a plain username */ + + pw = Get_Pwnam(mapped_username); + + /* Create local user if requested. */ + + if ( !pw && create ) { + /* Don't add a machine account. */ + if (mapped_username[strlen(mapped_username)-1] == '$') + return NULL; + + auth_add_user_script(NULL, mapped_username); pw = Get_Pwnam(mapped_username); - if (!pw) { - /* Don't add a machine account. */ - if (mapped_username[strlen(mapped_username)-1] == '$') - return NULL; - - /* Create local user if requested. */ - p = strchr( mapped_username, *lp_winbind_separator() ); - if (p) - p += 1; - else - p = mapped_username; - auth_add_user_script(NULL, p); - return Get_Pwnam(p); - } } + + /* one last check for a valid passwd struct */ + + if ( pw ) + fstrcpy( save_username, pw->pw_name ); return pw; } diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index c42a35e809..d91aa94728 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -143,7 +143,7 @@ static int reply_spnego_kerberos(connection_struct *conn, DATA_BLOB ticket; char *client, *p, *domain; fstring netbios_domain_name; - const struct passwd *pw; + struct passwd *pw; char *user; int sess_vuid; NTSTATUS ret; @@ -154,6 +154,7 @@ static int reply_spnego_kerberos(connection_struct *conn, uint8 tok_id[2]; BOOL foreign = False; DATA_BLOB nullblob = data_blob(NULL, 0); + fstring real_username; ZERO_STRUCT(ticket); ZERO_STRUCT(auth_data); @@ -239,7 +240,9 @@ static int reply_spnego_kerberos(connection_struct *conn, asprintf(&user, "%s%c%s", domain, *lp_winbind_separator(), client); - pw = smb_getpwnam( user ); + /* lookup the passwd struct, create a new user if necessary */ + + pw = smb_getpwnam( user, real_username, True ); if (!pw) { DEBUG(1,("Username %s is invalid on this system\n",user)); @@ -251,10 +254,11 @@ static int reply_spnego_kerberos(connection_struct *conn, /* setup the string used by %U */ - sub_set_smb_name(pw->pw_name); + sub_set_smb_name( real_username ); reload_services(True); - if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info,pw))) { + if (!NT_STATUS_IS_OK(ret = make_server_info_pw(&server_info, real_username, pw))) + { DEBUG(1,("make_server_info_from_pw failed!\n")); SAFE_FREE(user); SAFE_FREE(client); |