auth_util.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,706 行 · 第 1/4 页
C
1,706 行
return nt_status;}/*************************************************************************** Make (and fill) a user_info struct from a SAM_ACCOUNT***************************************************************************/NTSTATUS make_server_info_sam(auth_serversupplied_info **server_info, SAM_ACCOUNT *sampass){ NTSTATUS nt_status; struct passwd *pwd; if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) return nt_status; (*server_info)->sam_account = sampass; if ( !(pwd = getpwnam_alloc(pdb_get_username(sampass))) ) { DEBUG(1, ("User %s in passdb, but getpwnam() fails!\n", pdb_get_username(sampass))); free_server_info(server_info); return NT_STATUS_NO_SUCH_USER; } (*server_info)->unix_name = smb_xstrdup(pwd->pw_name); (*server_info)->gid = pwd->pw_gid; (*server_info)->uid = pwd->pw_uid; passwd_free(&pwd); if (!NT_STATUS_IS_OK(nt_status = add_user_groups(server_info, pdb_get_username(sampass), sampass, (*server_info)->uid, (*server_info)->gid))) { free_server_info(server_info); return nt_status; } (*server_info)->sam_fill_level = SAM_FILL_ALL; DEBUG(5,("make_server_info_sam: made server info for user %s -> %s\n", pdb_get_username(sampass), (*server_info)->unix_name)); return nt_status;}/*************************************************************************** Make (and fill) a user_info struct from a Kerberos PAC logon_info by conversion to a SAM_ACCOUNT***************************************************************************/NTSTATUS make_server_info_pac(auth_serversupplied_info **server_info, char *unix_username, struct passwd *pwd, PAC_LOGON_INFO *logon_info){ NTSTATUS nt_status; SAM_ACCOUNT *sampass = NULL; DOM_SID user_sid, group_sid; fstring dom_name; if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) { return nt_status; } if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) { return nt_status; } /* only copy user_sid, group_sid and domain name out of the PAC for * now, we will benefit from more later - Guenther */ sid_copy(&user_sid, &logon_info->info3.dom_sid.sid); sid_append_rid(&user_sid, logon_info->info3.user_rid); pdb_set_user_sid(sampass, &user_sid, PDB_SET); sid_copy(&group_sid, &logon_info->info3.dom_sid.sid); sid_append_rid(&group_sid, logon_info->info3.group_rid); pdb_set_group_sid(sampass, &group_sid, PDB_SET); unistr2_to_ascii(dom_name, &logon_info->info3.uni_logon_dom, -1); pdb_set_domain(sampass, dom_name, PDB_SET); pdb_set_logon_count(sampass, logon_info->info3.logon_count, PDB_SET); (*server_info)->sam_account = sampass; 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(unix_username); (*server_info)->sam_fill_level = SAM_FILL_ALL; (*server_info)->uid = pwd->pw_uid; (*server_info)->gid = pwd->pw_gid; return nt_status;}/*************************************************************************** Make (and fill) a user_info struct from a 'struct passwd' by conversion to a SAM_ACCOUNT***************************************************************************/NTSTATUS make_server_info_pw(auth_serversupplied_info **server_info, char *unix_username, struct passwd *pwd){ NTSTATUS nt_status; SAM_ACCOUNT *sampass = NULL; if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam_pw(&sampass, pwd))) { return nt_status; } if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) { return nt_status; } (*server_info)->sam_account = sampass; 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(unix_username); (*server_info)->sam_fill_level = SAM_FILL_ALL; (*server_info)->uid = pwd->pw_uid; (*server_info)->gid = pwd->pw_gid; return nt_status;}/*************************************************************************** Make (and fill) a user_info struct for a guest login.***************************************************************************/static NTSTATUS make_new_server_info_guest(auth_serversupplied_info **server_info){ NTSTATUS nt_status; SAM_ACCOUNT *sampass = NULL; DOM_SID guest_sid; if (!NT_STATUS_IS_OK(nt_status = pdb_init_sam(&sampass))) { return nt_status; } sid_copy(&guest_sid, get_global_sam_sid()); sid_append_rid(&guest_sid, DOMAIN_USER_RID_GUEST); become_root(); if (!pdb_getsampwsid(sampass, &guest_sid)) { unbecome_root(); return NT_STATUS_NO_SUCH_USER; } unbecome_root(); nt_status = make_server_info_sam(server_info, sampass); if (NT_STATUS_IS_OK(nt_status)) { static const char zeros[16]; (*server_info)->guest = True; /* annoying, but the Guest really does have a session key, and it is all zeros! */ (*server_info)->user_session_key = data_blob(zeros, sizeof(zeros)); (*server_info)->lm_session_key = data_blob(zeros, sizeof(zeros)); } return nt_status;}static auth_serversupplied_info *copy_serverinfo(auth_serversupplied_info *src){ auth_serversupplied_info *dst; if (!NT_STATUS_IS_OK(make_server_info(&dst))) return NULL; dst->guest = src->guest; dst->uid = src->uid; dst->gid = src->gid; dst->n_groups = src->n_groups; if (src->n_groups != 0) dst->groups = memdup(src->groups, sizeof(gid_t)*dst->n_groups); else dst->groups = NULL; dst->ptok = dup_nt_token(src->ptok); dst->user_session_key = data_blob(src->user_session_key.data, src->user_session_key.length); dst->lm_session_key = data_blob(src->lm_session_key.data, src->lm_session_key.length); pdb_copy_sam_account(src->sam_account, &dst->sam_account); dst->pam_handle = NULL; dst->unix_name = smb_xstrdup(src->unix_name); return dst;}static auth_serversupplied_info *guest_info = NULL;BOOL init_guest_info(void){ if (guest_info != NULL) return True; return NT_STATUS_IS_OK(make_new_server_info_guest(&guest_info));}NTSTATUS make_server_info_guest(auth_serversupplied_info **server_info){ *server_info = copy_serverinfo(guest_info); return (*server_info != NULL) ? NT_STATUS_OK : NT_STATUS_NO_MEMORY;}/*************************************************************************** Purely internal function for make_server_info_info3 Fill the sam account from getpwnam***************************************************************************/static NTSTATUS fill_sam_account(TALLOC_CTX *mem_ctx, const char *domain, const char *username, char **found_username, uid_t *uid, gid_t *gid, SAM_ACCOUNT **sam_account){ NTSTATUS nt_status; fstring dom_user, lower_username; fstring real_username; struct passwd *passwd; fstrcpy( lower_username, username ); strlower_m( lower_username ); fstr_sprintf(dom_user, "%s%c%s", domain, *lp_winbind_separator(), lower_username); /* 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 */ map_username( dom_user ); 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 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, real_username ); DEBUG(5,("fill_sam_account: located username was [%s]\n", *found_username)); nt_status = pdb_init_sam_pw(sam_account, passwd); passwd_free(&passwd); return nt_status;}/**************************************************************************** Wrapper to allow the getpwnam() call to strip the domain name and try again in case a local UNIX user is already there. Also run through the username if we fallback to the username only. ****************************************************************************/ struct passwd *smb_getpwnam( char *domuser, fstring save_username, BOOL create ){ struct passwd *pw = NULL; char *p; fstring username; /* we only save a copy of the username it has been mangled by winbindd use default domain */ save_username[0] = '\0'; /* don't call map_username() here since it has to be done higher up the stack so we don't call it mutliple times */ fstrcpy( username, domuser ); p = strchr_m( username, *lp_winbind_separator() ); /* code for a DOMAIN\user string */ if ( p ) { fstring strip_username; pw = Get_Pwnam_alloc( domuser ); if ( pw ) { /* make sure we get the case of the username correct */ /* work around 'winbind use default domain = yes' */ if ( !strchr_m( pw->pw_name, *lp_winbind_separator() ) ) { char *domain; /* split the domain and username into 2 strings */ *p = '\0'; domain = username; fstr_sprintf(save_username, "%s%c%s", domain, *lp_winbind_separator(), pw->pw_name); } else fstrcpy( save_username, pw->pw_name ); /* whew -- done! */ return pw; } /* setup for lookup of just the username */ /* remember that p and username are overlapping memory */ p++; fstrcpy( strip_username, p ); fstrcpy( username, strip_username ); } /* just lookup a plain username */ pw = Get_Pwnam_alloc(username); /* Create local user if requested. */ if ( !pw && create ) { /* Don't add a machine account. */ if (username[strlen(username)-1] == '$') return NULL; smb_create_user(NULL, username, NULL); pw = Get_Pwnam_alloc(username); } /* one last check for a valid passwd struct */ if ( pw ) fstrcpy( save_username, pw->pw_name ); return pw;}/*************************************************************************** Make a server_info struct from the info3 returned by a domain logon ***************************************************************************/NTSTATUS make_server_info_info3(TALLOC_CTX *mem_ctx, const char *internal_username, const char *sent_nt_username, const char *domain, auth_serversupplied_info **server_info, NET_USER_INFO_3 *info3) { static const char zeros[16]; NTSTATUS nt_status = NT_STATUS_OK; char *found_username; const char *nt_domain; const char *nt_username; SAM_ACCOUNT *sam_account = NULL; DOM_SID user_sid; DOM_SID group_sid; uid_t uid; gid_t gid; size_t n_lgroupSIDs; DOM_SID *lgroupSIDs = NULL; gid_t *unix_groups = NULL; NT_USER_TOKEN *token; DOM_SID *all_group_SIDs; size_t i; /* Here is where we should check the list of trusted domains, and verify that the SID matches. */ sid_copy(&user_sid, &info3->dom_sid.sid); if (!sid_append_rid(&user_sid, info3->user_rid)) { return NT_STATUS_INVALID_PARAMETER; } sid_copy(&group_sid, &info3->dom_sid.sid); if (!sid_append_rid(&group_sid, info3->group_rid)) { return NT_STATUS_INVALID_PARAMETER; } if (!(nt_username = unistr2_tdup(mem_ctx, &(info3->uni_user_name)))) { /* If the server didn't give us one, just use the one we sent them */ nt_username = sent_nt_username; } if (!(nt_domain = unistr2_tdup(mem_ctx, &(info3->uni_logon_dom)))) { /* If the server didn't give us one, just use the one we sent them */ nt_domain = domain; } /* try to fill the SAM account.. If getpwnam() fails, then try the add user script (2.2.x behavior). We use the _unmapped_ username here in an attempt to provide consistent username mapping behavior between kerberos and NTLM[SSP] authentication in domain mode security. I.E. Username mapping should be applied to the fully qualified username (e.g. DOMAIN\user) and no just the login name. Yes this mean swe called map_username() unnecessarily in make_user_info_map() but that is how the current code is designed. Making the change here is the least disruptive place. -- jerry */ nt_status = fill_sam_account(mem_ctx, nt_domain, sent_nt_username, &found_username, &uid, &gid, &sam_account); if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?