auth_util.c
来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,706 行 · 第 1/4 页
C
1,706 行
{ fstring sid_str; size_t i; if (!token) { DEBUGC(dbg_class, dbg_lev, ("NT user token: (NULL)\n")); return; } DEBUGC(dbg_class, dbg_lev, ("NT user token of user %s\n", sid_to_string(sid_str, &token->user_sids[0]) )); DEBUGADDC(dbg_class, dbg_lev, ("contains %lu SIDs\n", (unsigned long)token->num_sids)); for (i = 0; i < token->num_sids; i++) DEBUGADDC(dbg_class, dbg_lev, ("SID[%3lu]: %s\n", (unsigned long)i, sid_to_string(sid_str, &token->user_sids[i]))); dump_se_priv( dbg_class, dbg_lev, &token->privileges );}/**************************************************************************** prints a UNIX 'token' to debug output.****************************************************************************/void debug_unix_user_token(int dbg_class, int dbg_lev, uid_t uid, gid_t gid, int n_groups, gid_t *groups){ int i; DEBUGC(dbg_class, dbg_lev, ("UNIX token of user %ld\n", (long int)uid)); DEBUGADDC(dbg_class, dbg_lev, ("Primary group is %ld and contains %i supplementary groups\n", (long int)gid, n_groups)); for (i = 0; i < n_groups; i++) DEBUGADDC(dbg_class, dbg_lev, ("Group[%3i]: %ld\n", i, (long int)groups[i]));}/**************************************************************************** Create the SID list for this user.****************************************************************************/static NTSTATUS create_nt_user_token(const DOM_SID *user_sid, const DOM_SID *group_sid, int n_groupSIDs, DOM_SID *groupSIDs, BOOL is_guest, NT_USER_TOKEN **token){ NTSTATUS nt_status = NT_STATUS_OK; NT_USER_TOKEN *ptoken; int i; int sid_ndx; DOM_SID domadm; BOOL is_domain_admin = False; BOOL domain_mode = False; if ((ptoken = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL) { DEBUG(0, ("create_nt_user_token: Out of memory allocating token\n")); nt_status = NT_STATUS_NO_MEMORY; return nt_status; } ZERO_STRUCTP(ptoken); ptoken->num_sids = n_groupSIDs + 5; if ((ptoken->user_sids = SMB_MALLOC_ARRAY( DOM_SID, ptoken->num_sids )) == NULL) { DEBUG(0, ("create_nt_user_token: Out of memory allocating SIDs\n")); nt_status = NT_STATUS_NO_MEMORY; return nt_status; } memset((char*)ptoken->user_sids,0,sizeof(DOM_SID) * ptoken->num_sids); /* * Note - user SID *MUST* be first in token ! * se_access_check depends on this. * * Primary group SID is second in token. Convention. */ sid_copy(&ptoken->user_sids[PRIMARY_USER_SID_INDEX], user_sid); if (group_sid) sid_copy(&ptoken->user_sids[PRIMARY_GROUP_SID_INDEX], group_sid); /* * 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(&ptoken->user_sids[2], &global_sid_World); sid_copy(&ptoken->user_sids[3], &global_sid_Network); if (is_guest) sid_copy(&ptoken->user_sids[4], &global_sid_Builtin_Guests); else sid_copy(&ptoken->user_sids[4], &global_sid_Authenticated_Users); sid_ndx = 5; /* next available spot */ /* this is where we construct the domain admins SID if we can so that we can add the BUILTIN\Administrators SID to the token */ ZERO_STRUCT( domadm ); if ( IS_DC || lp_server_role()==ROLE_DOMAIN_MEMBER ) { domain_mode = True; if ( IS_DC ) sid_copy( &domadm, get_global_sam_sid() ); else { /* if we a re a member server and cannot find out domain SID then reset the domain_mode flag */ if ( !secrets_fetch_domain_sid( lp_workgroup(), &domadm ) ) domain_mode = False; } sid_append_rid( &domadm, DOMAIN_GROUP_RID_ADMINS ); } /* add the group SIDs to teh token */ for (i = 0; i < n_groupSIDs; i++) { size_t check_sid_idx; for (check_sid_idx = 1; check_sid_idx < ptoken->num_sids; check_sid_idx++) { if (sid_equal(&ptoken->user_sids[check_sid_idx], &groupSIDs[i])) { break; } } if (check_sid_idx >= ptoken->num_sids) /* Not found already */ { sid_copy(&ptoken->user_sids[sid_ndx++], &groupSIDs[i]); } else { ptoken->num_sids--; } /* here we check if the user is a domain admin and add the BUILTIN\Administrators SID to the token the group membership check succeeds. */ if ( domain_mode ) { if ( sid_equal( &domadm, &groupSIDs[i] ) ) is_domain_admin = True; } } /* finally realloc the SID array and add the BUILTIN\Administrators SID if necessary */ if ( is_domain_admin ) { DOM_SID *sids; if ( !(sids = SMB_REALLOC_ARRAY( ptoken->user_sids, DOM_SID, ptoken->num_sids+1 )) ) DEBUG(0,("create_nt_user_token: Failed to realloc SID arry of size %d\n", ptoken->num_sids+1)); else { ptoken->user_sids = sids; sid_copy( &(ptoken->user_sids)[ptoken->num_sids++], &global_sid_Builtin_Administrators ); } } /* add privileges assigned to this user */ get_privileges_for_sids( &ptoken->privileges, ptoken->user_sids, ptoken->num_sids ); debug_nt_user_token(DBGC_AUTH, 10, ptoken); if ((lp_log_nt_token_command() != NULL) && (strlen(lp_log_nt_token_command()) > 0)) { TALLOC_CTX *mem_ctx; char *command; fstring sidstr; char *user_sidstr, *group_sidstr; mem_ctx = talloc_init("setnttoken"); if (mem_ctx == NULL) return NT_STATUS_NO_MEMORY; sid_to_string(sidstr, &ptoken->user_sids[0]); user_sidstr = talloc_strdup(mem_ctx, sidstr); group_sidstr = talloc_strdup(mem_ctx, ""); for (i=1; i<ptoken->num_sids; i++) { sid_to_string(sidstr, &ptoken->user_sids[i]); group_sidstr = talloc_asprintf(mem_ctx, "%s %s", group_sidstr, sidstr); } command = SMB_STRDUP(lp_log_nt_token_command()); command = realloc_string_sub(command, "%s", user_sidstr); command = realloc_string_sub(command, "%t", group_sidstr); DEBUG(8, ("running command: [%s]\n", command)); if (smbrun(command, NULL) != 0) { DEBUG(0, ("Could not log NT token\n")); nt_status = NT_STATUS_ACCESS_DENIED; } talloc_destroy(mem_ctx); SAFE_FREE(command); } *token = ptoken; return nt_status;}/**************************************************************************** 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){ DOM_SID user_sid; DOM_SID group_sid; DOM_SID *group_sids; NT_USER_TOKEN *token; int i; if (!NT_STATUS_IS_OK(uid_to_sid(&user_sid, uid))) { return NULL; } if (!NT_STATUS_IS_OK(gid_to_sid(&group_sid, gid))) { return NULL; } group_sids = SMB_MALLOC_ARRAY(DOM_SID, ngroups); if (!group_sids) { DEBUG(0, ("create_nt_token: malloc() failed for DOM_SID list!\n")); return NULL; } /* convert the Unix group ids to SIDS */ for (i = 0; i < ngroups; i++) { if (!NT_STATUS_IS_OK(gid_to_sid(&(group_sids)[i], (groups)[i]))) { DEBUG(1, ("create_nt_token: failed to convert gid %ld to a sid!\n", (long int)groups[i])); SAFE_FREE(group_sids); return NULL; } } if (!NT_STATUS_IS_OK(create_nt_user_token(&user_sid, &group_sid, ngroups, group_sids, is_guest, &token))) { SAFE_FREE(group_sids); return NULL; } SAFE_FREE(group_sids); return token;}/****************************************************************************** Create a token for the root user to be used internally by smbd. This is similar to running under the context of the LOCAL_SYSTEM account in Windows. This is a read-only token. Do not modify it or free() it. Create a copy if your need to change it.******************************************************************************/NT_USER_TOKEN *get_root_nt_token( void ){ static NT_USER_TOKEN *token = NULL; DOM_SID u_sid, g_sid; DOM_SID g_sids[1]; struct passwd *pw; NTSTATUS result; if ( token ) return token; if ( !(pw = getpwnam( "root" )) ) { DEBUG(0,("get_root_nt_token: getpwnam\"root\") failed!\n")); return NULL; } /* get the user and primary group SIDs; although the BUILTIN\Administrators SId is really the one that matters here */ if ( !NT_STATUS_IS_OK(uid_to_sid(&u_sid, pw->pw_uid)) ) return NULL; if ( !NT_STATUS_IS_OK(gid_to_sid(&g_sid, pw->pw_gid)) ) return NULL; sid_copy( &g_sids[0], &global_sid_Builtin_Administrators ); result = create_nt_user_token( &u_sid, &g_sid, 1, g_sids, False, &token); return NT_STATUS_IS_OK(result) ? token : NULL;}/****************************************************************************** * this function returns the groups (SIDs) of the local SAM the user is in. * If this samba server is a DC of the domain the user belongs to, it returns * both domain groups and local / builtin groups. If the user is in a trusted * domain, or samba is a member server of a domain, then this function returns * local and builtin groups the user is a member of. * * currently this is a hack, as there is no sam implementation that is capable * of groups. * * NOTE!! This function will fail if you pass in a winbind user without * the domain --jerry ******************************************************************************/static NTSTATUS get_user_groups(const char *username, uid_t uid, gid_t gid, size_t *n_groups, DOM_SID **groups, gid_t **unix_groups){ int n_unix_groups; int i; *n_groups = 0; *groups = NULL; if (strchr(username, *lp_winbind_separator()) == NULL) { NTSTATUS result; become_root(); result = pdb_enum_group_memberships(username, gid, groups, unix_groups, n_groups); unbecome_root(); return result; } /* We have the separator, this must be winbind */ n_unix_groups = winbind_getgroups( username, unix_groups ); DEBUG(10,("get_user_groups: winbind_getgroups(%s): result = %s\n", username, n_unix_groups == -1 ? "FAIL" : "SUCCESS")); if ( n_unix_groups == -1 ) return NT_STATUS_NO_SUCH_USER; /* what should this return * value be? */ debug_unix_user_token(DBGC_CLASS, 5, uid, gid, n_unix_groups, *unix_groups); /* now setup the space for storing the SIDS */ if (n_unix_groups > 0) { *groups = SMB_MALLOC_ARRAY(DOM_SID, n_unix_groups); if (!*groups) { DEBUG(0, ("get_user_group: malloc() failed for DOM_SID list!\n")); SAFE_FREE(*unix_groups); return NT_STATUS_NO_MEMORY; } } *n_groups = n_unix_groups; for (i = 0; i < *n_groups; i++) { if (!NT_STATUS_IS_OK(gid_to_sid(&(*groups)[i], (*unix_groups)[i]))) { DEBUG(1, ("get_user_groups: failed to convert gid %ld to a sid!\n", (long int)(*unix_groups)[i+1])); SAFE_FREE(*groups); SAFE_FREE(*unix_groups); return NT_STATUS_NO_SUCH_USER; } } return NT_STATUS_OK;}/*************************************************************************** Make a user_info struct***************************************************************************/static NTSTATUS make_server_info(auth_serversupplied_info **server_info){ *server_info = SMB_MALLOC_P(auth_serversupplied_info); if (!*server_info) { DEBUG(0,("make_server_info: malloc failed!\n")); return NT_STATUS_NO_MEMORY; } ZERO_STRUCTP(*server_info); /* Initialise the uid and gid values to something non-zero which may save us from giving away root access if there is a bug in allocating these fields. */ (*server_info)->uid = -1; (*server_info)->gid = -1; return NT_STATUS_OK;}/***************************************************************************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){ NTSTATUS nt_status; const DOM_SID *user_sid = pdb_get_user_sid(sampass); const DOM_SID *group_sid = pdb_get_group_sid(sampass); size_t n_groupSIDs = 0; DOM_SID *groupSIDs = NULL; gid_t *unix_groups = NULL; NT_USER_TOKEN *token; BOOL is_guest; uint32 rid; nt_status = get_user_groups(unix_username, uid, gid, &n_groupSIDs, &groupSIDs, &unix_groups); if (!NT_STATUS_IS_OK(nt_status)) { DEBUG(4,("get_user_groups_from_local_sam failed\n")); free_server_info(server_info); return nt_status; } is_guest = (sid_peek_rid(user_sid, &rid) && rid == DOMAIN_USER_RID_GUEST); if (!NT_STATUS_IS_OK(nt_status = create_nt_user_token(user_sid, group_sid, n_groupSIDs, groupSIDs, is_guest, &token))) { DEBUG(4,("create_nt_user_token failed\n")); SAFE_FREE(groupSIDs); SAFE_FREE(unix_groups); free_server_info(server_info); return nt_status; } SAFE_FREE(groupSIDs); (*server_info)->n_groups = n_groupSIDs; (*server_info)->groups = unix_groups; (*server_info)->ptok = token;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?