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/auth/auth_ntlmssp.c | 2 +- source3/auth/auth_rhosts.c | 68 +++++++++++++++++++++++------------------ source3/auth/auth_util.c | 73 +++++++++++++++++++++++++++++---------------- 3 files changed, 87 insertions(+), 56 deletions(-) (limited to 'source3/auth') diff --git a/source3/auth/auth_ntlmssp.c b/source3/auth/auth_ntlmssp.c index 43542b2474..d32d248296 100644 --- a/source3/auth/auth_ntlmssp.c +++ b/source3/auth/auth_ntlmssp.c @@ -131,7 +131,7 @@ NTSTATUS auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state) } NTSTATUS auth_ntlmssp_update(AUTH_NTLMSSP_STATE *auth_ntlmssp_state, - DATA_BLOB request, DATA_BLOB *reply) + const DATA_BLOB request, DATA_BLOB *reply) { return ntlmssp_server_update(auth_ntlmssp_state->ntlmssp_state, request, reply); } diff --git a/source3/auth/auth_rhosts.c b/source3/auth/auth_rhosts.c index 4ed0e6bbc4..5451f7d930 100644 --- a/source3/auth/auth_rhosts.c +++ b/source3/auth/auth_rhosts.c @@ -129,23 +129,19 @@ static BOOL check_user_equiv(const char *user, const char *remote, const char *e return False; } - /**************************************************************************** check for a possible hosts equiv or rhosts entry for the user ****************************************************************************/ -static BOOL check_hosts_equiv(struct passwd *pass) +static BOOL check_hosts_equiv(SAM_ACCOUNT *account) { char *fname = NULL; - 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(pass->pw_name,client_name(),fname)) + if (IS_SAM_UNIX_USER(account) && fname && *fname && (pdb_get_uid(account) != 0)) { + if (check_user_equiv(pdb_get_username(account),client_name(),fname)) return(True); } @@ -164,15 +160,18 @@ static NTSTATUS check_hostsequiv_security(const struct auth_context *auth_contex auth_serversupplied_info **server_info) { NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; - struct passwd *pass = Get_Pwnam(user_info->internal_username.str); - - if (pass) { - if (check_hosts_equiv(pass)) { - nt_status = NT_STATUS_OK; - make_server_info_pw(server_info, pass); - } + SAM_ACCOUNT *account = NULL; + if (!NT_STATUS_IS_OK(nt_status = + auth_get_sam_account(user_info->internal_username.str, + &account))) { + return nt_status; + } + + if (check_hosts_equiv(account)) { + nt_status = make_server_info_sam(server_info, account); } else { - nt_status = NT_STATUS_NO_SUCH_USER; + pdb_free_sam(&account); + nt_status = NT_STATUS_LOGON_FAILURE; } return nt_status; @@ -186,6 +185,7 @@ NTSTATUS auth_init_hostsequiv(struct auth_context *auth_context, const char* par } (*auth_method)->auth = check_hostsequiv_security; + (*auth_method)->name = "hostsequiv"; return NT_STATUS_OK; } @@ -201,24 +201,33 @@ static NTSTATUS check_rhosts_security(const struct auth_context *auth_context, auth_serversupplied_info **server_info) { NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE; - struct passwd *pass = Get_Pwnam(user_info->internal_username.str); + SAM_ACCOUNT *account = NULL; pstring rhostsfile; + const char *home; - if (pass) { - char *home = pass->pw_dir; - if (home) { - slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); - become_root(); - if (check_user_equiv(pass->pw_name,client_name(),rhostsfile)) { - nt_status = NT_STATUS_OK; - make_server_info_pw(server_info, pass); - } - unbecome_root(); - } - } else { - nt_status = NT_STATUS_NO_SUCH_USER; + if (!NT_STATUS_IS_OK(nt_status = + auth_get_sam_account(user_info->internal_username.str, + &account))) { + return nt_status; } + home = pdb_get_unix_homedir(account); + + if (home) { + slprintf(rhostsfile, sizeof(rhostsfile)-1, "%s/.rhosts", home); + become_root(); + if (check_user_equiv(pdb_get_username(account),client_name(),rhostsfile)) { + nt_status = make_server_info_sam(server_info, account); + } else { + pdb_free_sam(&account); + nt_status = NT_STATUS_LOGON_FAILURE; + } + unbecome_root(); + } else { + pdb_free_sam(&account); + nt_status = NT_STATUS_LOGON_FAILURE; + } + return nt_status; } @@ -230,5 +239,6 @@ NTSTATUS auth_init_rhosts(struct auth_context *auth_context, const char *param, } (*auth_method)->auth = check_rhosts_security; + (*auth_method)->name = "rhosts"; return NT_STATUS_OK; } diff --git a/source3/auth/auth_util.c b/source3/auth/auth_util.c index bbe0c7cf43..7d85153bd0 100644 --- a/source3/auth/auth_util.c +++ b/source3/auth/auth_util.c @@ -77,6 +77,36 @@ void smb_user_control(const auth_usersupplied_info *user_info, auth_serversuppli } } +/**************************************************************************** + Create a SAM_ACCOUNT - either by looking in the pdb, or by faking it up from + unix info. +****************************************************************************/ + +NTSTATUS auth_get_sam_account(const char *user, SAM_ACCOUNT **account) +{ + BOOL pdb_ret; + NTSTATUS nt_status; + if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(account))) { + return nt_status; + } + + become_root(); + pdb_ret = pdb_getsampwnam(*account, user); + unbecome_root(); + + if (!pdb_ret) { + + struct passwd *pass = Get_Pwnam(user); + if (!pass) + return NT_STATUS_NO_SUCH_USER; + + if (!NT_STATUS_IS_OK(nt_status = pdb_fill_sam_pw(*account, pass))) { + return nt_status; + } + } + return NT_STATUS_OK; +} + /**************************************************************************** Create an auth_usersupplied_data structure ****************************************************************************/ @@ -641,34 +671,25 @@ NT_USER_TOKEN *create_nt_token(uid_t uid, gid_t gid, int ngroups, gid_t *groups, * of groups. ******************************************************************************/ -static NTSTATUS get_user_groups_from_local_sam(const DOM_SID *user_sid, +static NTSTATUS get_user_groups_from_local_sam(SAM_ACCOUNT *sampass, int *n_groups, DOM_SID **groups, gid_t **unix_groups) { uid_t uid; - enum SID_NAME_USE snu; - fstring str; + gid_t gid; int n_unix_groups; int i; struct passwd *usr; - + *n_groups = 0; *groups = NULL; - - if (!sid_to_uid(user_sid, &uid, &snu)) { - DEBUG(2, ("get_user_groups_from_local_sam: Failed to convert user SID %s to a uid!\n", - sid_to_string(str, user_sid))); - /* This might be a non-unix account */ - return NT_STATUS_OK; - } - /* - * This is _essential_ to prevent occasional segfaults when - * winbind can't find uid -> username mapping - */ - if (!(usr = getpwuid_alloc(uid))) { - DEBUG(0, ("Couldn't find passdb structure for UID = %d ! Aborting.\n", uid)); + if (!IS_SAM_UNIX_USER(sampass)) { + DEBUG(1, ("user %s does not have a unix identity!\n", pdb_get_username(sampass))); return NT_STATUS_NO_SUCH_USER; - }; + } + + uid = pdb_get_uid(sampass); + gid = pdb_get_gid(sampass); n_unix_groups = groups_max(); if ((*unix_groups = malloc( sizeof(gid_t) * n_unix_groups ) ) == NULL) { @@ -677,7 +698,7 @@ static NTSTATUS get_user_groups_from_local_sam(const DOM_SID *user_sid, return NT_STATUS_NO_MEMORY; } - if (sys_getgrouplist(usr->pw_name, usr->pw_gid, *unix_groups, &n_unix_groups) == -1) { + if (sys_getgrouplist(pdb_get_username(sampass), gid, *unix_groups, &n_unix_groups) == -1) { gid_t *groups_tmp; groups_tmp = Realloc(*unix_groups, sizeof(gid_t) * n_unix_groups); if (!groups_tmp) { @@ -687,7 +708,7 @@ static NTSTATUS get_user_groups_from_local_sam(const DOM_SID *user_sid, } *unix_groups = groups_tmp; - if (sys_getgrouplist(usr->pw_name, usr->pw_gid, *unix_groups, &n_unix_groups) == -1) { + if (sys_getgrouplist(pdb_get_username(sampass), gid, *unix_groups, &n_unix_groups) == -1) { DEBUG(0, ("get_user_groups_from_local_sam: failed to get the unix group list\n")); SAFE_FREE(*unix_groups); passwd_free(&usr); @@ -695,9 +716,7 @@ static NTSTATUS get_user_groups_from_local_sam(const DOM_SID *user_sid, } } - debug_unix_user_token(DBGC_CLASS, 5, usr->pw_uid, usr->pw_gid, n_unix_groups, *unix_groups); - - passwd_free(&usr); + debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups); if (n_unix_groups > 0) { *groups = malloc(sizeof(DOM_SID) * n_unix_groups); @@ -763,7 +782,7 @@ NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, } if (!NT_STATUS_IS_OK(nt_status - = get_user_groups_from_local_sam(pdb_get_user_sid(sampass), + = get_user_groups_from_local_sam(sampass, &n_groupSIDs, &groupSIDs, &unix_groups))) { DEBUG(4,("get_user_groups_from_local_sam failed\n")); @@ -838,7 +857,9 @@ NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info) nt_status = make_server_info_sam(server_info, sampass); - (*server_info)->guest = True; + if (NT_STATUS_IS_OK(nt_status)) { + (*server_info)->guest = True; + } return nt_status; } @@ -996,7 +1017,7 @@ NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, returned to the caller. */ if (!NT_STATUS_IS_OK(nt_status - = get_user_groups_from_local_sam(&user_sid, + = get_user_groups_from_local_sam(sam_account, &n_lgroupSIDs, &lgroupSIDs, &unix_groups))) -- cgit