auth_util.c

来自「samba-3.0.22.tar.gz 编译smb服务器的源码」· C语言 代码 · 共 1,706 行 · 第 1/4 页

C
1,706
字号
		DEBUG(3,("User %s does not exist, trying to add it\n", internal_username));		smb_create_user( nt_domain, sent_nt_username, NULL);		nt_status = fill_sam_account( mem_ctx, nt_domain, sent_nt_username, 			&found_username, &uid, &gid, &sam_account );	}		/* if we still don't have a valid unix account check for 	  'map to gues = bad uid' */	  	if (!NT_STATUS_IS_OK(nt_status)) {		if ( lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID ) {		 	make_server_info_guest(server_info); 			return NT_STATUS_OK;		}				DEBUG(0, ("make_server_info_info3: pdb_init_sam failed!\n"));		return nt_status;	}			if (!pdb_set_nt_username(sam_account, nt_username, PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_username(sam_account, nt_username, PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_domain(sam_account, nt_domain, PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_user_sid(sam_account, &user_sid, PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_UNSUCCESSFUL;	}	if (!pdb_set_group_sid(sam_account, &group_sid, PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_UNSUCCESSFUL;	}			if (!pdb_set_fullname(sam_account, unistr2_static(&(info3->uni_full_name)), 			      PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_logon_script(sam_account, unistr2_static(&(info3->uni_logon_script)), PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_profile_path(sam_account, unistr2_static(&(info3->uni_profile_path)), PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_homedir(sam_account, unistr2_static(&(info3->uni_home_dir)), PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!pdb_set_dir_drive(sam_account, unistr2_static(&(info3->uni_dir_drive)), PDB_CHANGED)) {		pdb_free_sam(&sam_account);		return NT_STATUS_NO_MEMORY;	}	if (!NT_STATUS_IS_OK(nt_status = make_server_info(server_info))) {		DEBUG(4, ("make_server_info failed!\n"));		pdb_free_sam(&sam_account);		return nt_status;	}	/* save this here to _net_sam_logon() doesn't fail (it assumes a 	   valid SAM_ACCOUNT) */		   	(*server_info)->sam_account = sam_account;	(*server_info)->unix_name = smb_xstrdup(found_username);	/* Fill in the unix info we found on the way */	(*server_info)->sam_fill_level = SAM_FILL_ALL;	(*server_info)->uid = uid;	(*server_info)->gid = gid;	/* Store the user group information in the server_info 	   returned to the caller. */		nt_status = get_user_groups((*server_info)->unix_name,		uid, gid, &n_lgroupSIDs, &lgroupSIDs, &unix_groups);			if ( !NT_STATUS_IS_OK(nt_status) ) {		DEBUG(4,("get_user_groups failed\n"));		return nt_status;	}	(*server_info)->groups = unix_groups;	(*server_info)->n_groups = n_lgroupSIDs;		/* Create a 'combined' list of all SIDs we might want in the SD */		all_group_SIDs = SMB_MALLOC_ARRAY(DOM_SID,info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs);		if (!all_group_SIDs) {		DEBUG(0, ("malloc() failed for DOM_SID list!\n"));		SAFE_FREE(lgroupSIDs);		free_server_info(server_info);		return NT_STATUS_NO_MEMORY;	}	/* and create (by appending rids) the 'domain' sids */		for (i = 0; i < info3->num_groups2; i++) {			sid_copy(&all_group_SIDs[i], &(info3->dom_sid.sid));				if (!sid_append_rid(&all_group_SIDs[i], info3->gids[i].g_rid)) {					nt_status = NT_STATUS_INVALID_PARAMETER;						DEBUG(3,("could not append additional group rid 0x%x\n",				info3->gids[i].g_rid));										SAFE_FREE(lgroupSIDs);			SAFE_FREE(all_group_SIDs);			free_server_info(server_info);						return nt_status;					}	}	/* Copy 'other' sids.  We need to do sid filtering here to 	   prevent possible elevation of privileges.  See:           http://www.microsoft.com/windows2000/techinfo/administration/security/sidfilter.asp         */	for (i = 0; i < info3->num_other_sids; i++) {		sid_copy(&all_group_SIDs[info3->num_groups2 + i],			 &info3->other_sids[i].sid);	}	/* add local alias sids */ 	for (i = 0; i < n_lgroupSIDs; i++) {		sid_copy(&all_group_SIDs[info3->num_groups2 +					 info3->num_other_sids + i],			 &lgroupSIDs[i]);	}		/* Where are the 'global' sids... */	/* can the user be guest? if yes, where is it stored? */		nt_status = create_nt_user_token(&user_sid, &group_sid,		info3->num_groups2 + info3->num_other_sids + n_lgroupSIDs,		all_group_SIDs, False, &token);			if ( !NT_STATUS_IS_OK(nt_status) ) {		DEBUG(4,("create_nt_user_token failed\n"));		SAFE_FREE(lgroupSIDs);		SAFE_FREE(all_group_SIDs);		free_server_info(server_info);		return nt_status;	}	(*server_info)->login_server = unistr2_tdup(mem_ctx, 						    &(info3->uni_logon_srv));	(*server_info)->ptok = token; 	SAFE_FREE(lgroupSIDs);	SAFE_FREE(all_group_SIDs);	/* ensure we are never given NULL session keys */		if (memcmp(info3->user_sess_key, zeros, sizeof(zeros)) == 0) {		(*server_info)->user_session_key = data_blob(NULL, 0);	} else {		(*server_info)->user_session_key = data_blob(info3->user_sess_key, sizeof(info3->user_sess_key));	}	if (memcmp(info3->lm_sess_key, zeros, 8) == 0) {		(*server_info)->lm_session_key = data_blob(NULL, 0);	} else {		(*server_info)->lm_session_key = data_blob(info3->lm_sess_key, sizeof(info3->lm_sess_key));	} 	return NT_STATUS_OK;}/*************************************************************************** Free a user_info struct***************************************************************************/void free_user_info(auth_usersupplied_info **user_info){	DEBUG(5,("attempting to free (and zero) a user_info structure\n"));	if (*user_info != NULL) {		if ((*user_info)->smb_name.str) {			DEBUG(10,("structure was created for %s\n", (*user_info)->smb_name.str));		}		SAFE_FREE((*user_info)->smb_name.str);		SAFE_FREE((*user_info)->internal_username.str);		SAFE_FREE((*user_info)->client_domain.str);		SAFE_FREE((*user_info)->domain.str);		SAFE_FREE((*user_info)->wksta_name.str);		data_blob_free(&(*user_info)->lm_resp);		data_blob_free(&(*user_info)->nt_resp);		data_blob_clear_free(&(*user_info)->lm_interactive_pwd);		data_blob_clear_free(&(*user_info)->nt_interactive_pwd);		data_blob_clear_free(&(*user_info)->plaintext_password);		ZERO_STRUCT(**user_info);	}	SAFE_FREE(*user_info);}/*************************************************************************** Clear out a server_info struct that has been allocated***************************************************************************/void free_server_info(auth_serversupplied_info **server_info){	DEBUG(5,("attempting to free (and zero) a server_info structure\n"));	if (*server_info != NULL) {		pdb_free_sam(&(*server_info)->sam_account);		/* call pam_end here, unless we know we are keeping it */		delete_nt_token( &(*server_info)->ptok );		SAFE_FREE((*server_info)->groups);		SAFE_FREE((*server_info)->unix_name);		data_blob_free(&(*server_info)->lm_session_key);		data_blob_free(&(*server_info)->user_session_key);		ZERO_STRUCT(**server_info);	}	SAFE_FREE(*server_info);}/*************************************************************************** Make an auth_methods struct***************************************************************************/BOOL make_auth_methods(struct auth_context *auth_context, auth_methods **auth_method) {	if (!auth_context) {		smb_panic("no auth_context supplied to make_auth_methods()!\n");	}	if (!auth_method) {		smb_panic("make_auth_methods: pointer to auth_method pointer is NULL!\n");	}	*auth_method = TALLOC_P(auth_context->mem_ctx, auth_methods);	if (!*auth_method) {		DEBUG(0,("make_auth_method: malloc failed!\n"));		return False;	}	ZERO_STRUCTP(*auth_method);		return True;}/**************************************************************************** Delete a SID token.****************************************************************************/void delete_nt_token(NT_USER_TOKEN **pptoken){	if (*pptoken) {		NT_USER_TOKEN *ptoken = *pptoken;		SAFE_FREE( ptoken->user_sids );		ZERO_STRUCTP(ptoken);	}	SAFE_FREE(*pptoken);}/**************************************************************************** Duplicate a SID token.****************************************************************************/NT_USER_TOKEN *dup_nt_token(NT_USER_TOKEN *ptoken){	NT_USER_TOKEN *token;	if (!ptoken)		return NULL;	if ((token = SMB_MALLOC_P(NT_USER_TOKEN)) == NULL)		return NULL;	ZERO_STRUCTP(token);		token->user_sids = (DOM_SID *)memdup( ptoken->user_sids, sizeof(DOM_SID) * ptoken->num_sids );		if ( !token ) {		SAFE_FREE(token);		return NULL;	}	token->num_sids = ptoken->num_sids;		/* copy the privileges; don't consider failure to be critical here */		if ( !se_priv_copy( &token->privileges, &ptoken->privileges ) ) {		DEBUG(0,("dup_nt_token: Failure to copy SE_PRIV!.  Continuing with 0 privileges assigned.\n"));	}	return token;}/**************************************************************************** Check for a SID in an NT_USER_TOKEN****************************************************************************/BOOL nt_token_check_sid ( DOM_SID *sid, NT_USER_TOKEN *token ){	int i;		if ( !sid || !token )		return False;		for ( i=0; i<token->num_sids; i++ ) {		if ( sid_equal( sid, &token->user_sids[i] ) )			return True;	}	return False;}BOOL nt_token_check_domain_rid( NT_USER_TOKEN *token, uint32 rid ) {	DOM_SID domain_sid;	/* if we are a domain member, the get the domain SID, else for 	   a DC or standalone server, use our own SID */	if ( lp_server_role() == ROLE_DOMAIN_MEMBER ) {		if ( !secrets_fetch_domain_sid( lp_workgroup(), &domain_sid ) ) {			DEBUG(1,("nt_token_check_domain_rid: Cannot lookup SID for domain [%s]\n",				lp_workgroup()));			return False;		}	} 	else		sid_copy( &domain_sid, get_global_sam_sid() );	sid_append_rid( &domain_sid, rid );		return nt_token_check_sid( &domain_sid, token );\}/** * Verify whether or not given domain is trusted. * * @param domain_name name of the domain to be verified * @return true if domain is one of the trusted once or *         false if otherwise **/BOOL is_trusted_domain(const char* dom_name){	DOM_SID trustdom_sid;	char *pass = NULL;	time_t lct;	BOOL ret;	/* no trusted domains for a standalone server */	if ( lp_server_role() == ROLE_STANDALONE )		return False;	/* if we are a DC, then check for a direct trust relationships */	if ( IS_DC ) {		become_root();		DEBUG (5,("is_trusted_domain: Checking for domain trust with [%s]\n",			dom_name ));		ret = secrets_fetch_trusted_domain_password(dom_name, &pass, &trustdom_sid, &lct);		unbecome_root();		SAFE_FREE(pass);		if (ret)			return True;	}	else {		NSS_STATUS result;		/* If winbind is around, ask it */		result = wb_is_trusted_domain(dom_name);		if (result == NSS_STATUS_SUCCESS) {			return True;		}		if (result == NSS_STATUS_NOTFOUND) {			/* winbind could not find the domain */			return False;		}		/* The only other possible result is that winbind is not up		   and running. We need to update the trustdom_cache		   ourselves */				update_trustdom_cache();	}	/* now the trustdom cache should be available a DC could still	 * have a transitive trust so fall back to the cache of trusted	 * domains (like a domain member would use  */	if ( trustdom_cache_fetch(dom_name, &trustdom_sid) ) {		return True;	}	return False;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?