Example #1
0
File: conn.c Project: jophxy/samba
void conn_free(connection_struct *conn)
{
	/* Free vfs_connection_struct */
	    
	if (conn->dl_handle != NULL) {
		/* Close dlopen() handle */
		sys_dlclose(conn->dl_handle);
	}

	DLIST_REMOVE(Connections, conn);

	if (conn->ngroups && conn->groups) {
		SAFE_FREE(conn->groups);
		conn->groups = NULL;
		conn->ngroups = 0;
	}

	delete_nt_token(&conn->nt_user_token);
	free_namearray(conn->veto_list);
	free_namearray(conn->hide_list);
	free_namearray(conn->veto_oplock_list);
	
	string_free(&conn->user);
	string_free(&conn->dirpath);
	string_free(&conn->connectpath);
	string_free(&conn->origpath);

	bitmap_clear(bmap, conn->cnum);
	num_open--;

	ZERO_STRUCTP(conn);
	SAFE_FREE(conn);
}
Example #2
0
void invalidate_vuid(uint16 vuid)
{
	user_struct *vuser = get_valid_user_struct(vuid);

	if (vuser == NULL)
		return;
	
	SAFE_FREE(vuser->homedir);
	SAFE_FREE(vuser->unix_homedir);
	SAFE_FREE(vuser->logon_script);
	
	session_yield(vuser);
	SAFE_FREE(vuser->session_keystr);

	free_server_info(&vuser->server_info);

	data_blob_free(&vuser->session_key);

	DLIST_REMOVE(validated_users, vuser);

	/* clear the vuid from the 'cache' on each connection, and
	   from the vuid 'owner' of connections */
	conn_clear_vuid_cache(vuid);

	SAFE_FREE(vuser->groups);
	delete_nt_token(&vuser->nt_user_token);
	SAFE_FREE(vuser);
	num_validated_vuids--;
}
Example #3
0
BOOL pop_sec_ctx(void)
{
	struct sec_ctx *ctx_p;
	struct sec_ctx *prev_ctx_p;

	/* Check for stack underflow */

	if (sec_ctx_stack_ndx == 0) {
		DEBUG(0, ("Security context stack underflow!\n"));
		smb_panic("Security context stack underflow!\n");
	}

	ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];

	/* Clear previous user info */

	ctx_p->uid = (uid_t)-1;
	ctx_p->gid = (gid_t)-1;

	SAFE_FREE(ctx_p->groups);
	ctx_p->ngroups = 0;

	delete_nt_token(&ctx_p->token);

	/* Pop back previous user */

	sec_ctx_stack_ndx--;

	gain_root();

	prev_ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];

#ifdef HAVE_SETGROUPS
	sys_setgroups(prev_ctx_p->ngroups, prev_ctx_p->groups);
#endif

	become_id(prev_ctx_p->uid, prev_ctx_p->gid);

	/* Update current_user stuff */

	current_user.uid = prev_ctx_p->uid;
	current_user.gid = prev_ctx_p->gid;
	current_user.ngroups = prev_ctx_p->ngroups;
	current_user.groups = prev_ctx_p->groups;
	current_user.nt_user_token = prev_ctx_p->token;

	DEBUG(3, ("pop_sec_ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", 
		(unsigned int)geteuid(), (unsigned int)getegid(), sec_ctx_stack_ndx));

	return True;
}
Example #4
0
void set_sec_ctx(uid_t uid, gid_t gid, int ngroups, gid_t *groups, NT_USER_TOKEN *token)
{
	struct sec_ctx *ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];
	
	/* Set the security context */

	DEBUG(3, ("setting sec ctx (%u, %u) - sec_ctx_stack_ndx = %d\n", 
		(unsigned int)uid, (unsigned int)gid, sec_ctx_stack_ndx));

	if (ngroups) {
		int i;

		DEBUG(3, ("%d user groups: \n", ngroups));
		for (i = 0; i < ngroups; i++) {
			DEBUGADD(3, ("%u ", (unsigned int)groups[i]));
		}

		DEBUG(3, ("\n"));
	}
	

	gain_root();

#ifdef HAVE_SETGROUPS
	sys_setgroups(ngroups, groups);
#endif

	ctx_p->ngroups = ngroups;

	SAFE_FREE(ctx_p->groups);
	if (token && (token == ctx_p->token))
		smb_panic("DUPLICATE_TOKEN");

	delete_nt_token(&ctx_p->token);
	
	ctx_p->groups = memdup(groups, sizeof(gid_t) * ngroups);
	ctx_p->token = dup_nt_token(token);

	become_id(uid, gid);

	ctx_p->uid = uid;
	ctx_p->gid = gid;

	/* Update current_user stuff */

	current_user.uid = uid;
	current_user.gid = gid;
	current_user.ngroups = ngroups;
	current_user.groups = groups;
	current_user.nt_user_token = ctx_p->token;
}
Example #5
0
BOOL push_sec_ctx(void)
{
	struct sec_ctx *ctx_p;

	/* Check we don't overflow our stack */

	if (sec_ctx_stack_ndx == MAX_SEC_CTX_DEPTH) {
		DEBUG(0, ("Security context stack overflow!\n"));
		smb_panic("Security context stack overflow!\n");
	}

	/* Store previous user context */

	sec_ctx_stack_ndx++;

	ctx_p = &sec_ctx_stack[sec_ctx_stack_ndx];

	ctx_p->uid = geteuid();
	ctx_p->gid = getegid();

 	DEBUG(3, ("push_sec_ctx(%u, %u) : sec_ctx_stack_ndx = %d\n", 
 		  (unsigned int)ctx_p->uid, (unsigned int)ctx_p->gid, sec_ctx_stack_ndx ));

	ctx_p->token = dup_nt_token(sec_ctx_stack[sec_ctx_stack_ndx-1].token);

	ctx_p->ngroups = sys_getgroups(0, NULL);

	if (ctx_p->ngroups != 0) {
		if (!(ctx_p->groups = malloc(ctx_p->ngroups * sizeof(gid_t)))) {
			DEBUG(0, ("Out of memory in push_sec_ctx()\n"));
			delete_nt_token(&ctx_p->token);
			return False;
		}

		sys_getgroups(ctx_p->ngroups, ctx_p->groups);
	} else {
		ctx_p->groups = NULL;
	}

	return True;
}
Example #6
0
BOOL change_to_user(connection_struct *conn, uint16 vuid)
{
	user_struct *vuser = get_valid_user_struct(vuid);
	int snum;
	gid_t gid;
	uid_t uid;
	char group_c;
	BOOL must_free_token = False;
	NT_USER_TOKEN *token = NULL;

	if (!conn) {
		DEBUG(2,("change_to_user: Connection not open\n"));
		return(False);
	}

	/*
	 * We need a separate check in security=share mode due to vuid
	 * always being UID_FIELD_INVALID. If we don't do this then
	 * in share mode security we are *always* changing uid's between
	 * SMB's - this hurts performance - Badly.
	 */

	if((lp_security() == SEC_SHARE) && (current_user.conn == conn) &&
	   (current_user.uid == conn->uid)) {
		DEBUG(4,("change_to_user: Skipping user change - already user\n"));
		return(True);
	} else if ((current_user.conn == conn) && 
		   (vuser != 0) && (current_user.vuid == vuid) && 
		   (current_user.uid == vuser->uid)) 
	{
		DEBUG(4,("change_to_user: Skipping user change - already user\n"));
		return True;
	}

	snum = SNUM(conn);

	if((vuser != NULL) && !check_user_ok(conn, vuser, snum))
		return False;

	if (conn->force_user || 
		conn->admin_user ||
	    (lp_security() == SEC_SHARE)) {
		uid = conn->uid;
		gid = conn->gid;
		current_user.groups = conn->groups;
		current_user.ngroups = conn->ngroups;
		token = conn->nt_user_token;
	} else {
		if (!vuser) {
			DEBUG(2,("change_to_user: Invalid vuid used %d\n",vuid));
			return(False);
		}
		uid = vuser->uid;
		gid = vuser->gid;
		current_user.ngroups = vuser->n_groups;
		current_user.groups  = vuser->groups;
		token = vuser->nt_user_token;
	}

	/*
	 * See if we should force group for this service.
	 * If so this overrides any group set in the force
	 * user code.
	 */

	if((group_c = *lp_force_group(snum))) {
		BOOL is_guest = False;

		if(group_c == '+') {

			/*
			 * Only force group if the user is a member of
			 * the service group. Check the group memberships for
			 * this user (we already have this) to
			 * see if we should force the group.
			 */

			int i;
			for (i = 0; i < current_user.ngroups; i++) {
				if (current_user.groups[i] == conn->gid) {
					gid = conn->gid;
					break;
				}
			}
		} else {
			gid = conn->gid;
		}

		/*
		 * We've changed the group list in the token - we must
		 * re-create it.
		 */

		if (vuser && vuser->guest)
			is_guest = True;

		token = create_nt_token(uid, gid, current_user.ngroups, current_user.groups, is_guest, NULL);
		must_free_token = True;
	}
	
	set_sec_ctx(uid, gid, current_user.ngroups, current_user.groups, token);

	/*
	 * Free the new token (as set_sec_ctx copies it).
	 */

	if (must_free_token)
		delete_nt_token(&token);

	current_user.conn = conn;
	current_user.vuid = vuid;

	DEBUG(5,("change_to_user uid=(%d,%d) gid=(%d,%d)\n",
		 (int)getuid(),(int)geteuid(),(int)getgid(),(int)getegid()));
  
	return(True);
}
Example #7
0
void add_supplementary_nt_login_groups(int *n_groups, gid_t **pp_groups, NT_USER_TOKEN **pptok)
{
	int total_groups;
	int current_n_groups = *n_groups;
	gid_t *final_groups = NULL;
	size_t i;
	NT_USER_TOKEN *ptok = *pptok;
	NT_USER_TOKEN *new_tok = NULL;
 
	if (!ptok || (ptok->num_sids == 0))
		return;

	new_tok = dup_nt_token(ptok);
	if (!new_tok) {
		DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new token\n"));
		return;
	}
	/* Leave the allocated space but empty the number of SIDs. */
	new_tok->num_sids = 0;

	total_groups = current_n_groups + ptok->num_sids;
 
	final_groups = (gid_t *)malloc(total_groups * sizeof(gid_t));
	if (!final_groups) {
		DEBUG(0,("add_supplementary_nt_login_groups: Failed to malloc new groups.\n"));
		delete_nt_token(&new_tok);
		return;
	}
 
	memcpy(final_groups, *pp_groups, current_n_groups * sizeof(gid_t));
	for (i = 0; i < ptok->num_sids; i++) {
		enum SID_NAME_USE sid_type;
		gid_t new_grp;
 
		if (sid_to_gid(&ptok->user_sids[i], &new_grp, &sid_type)) {
			/*
			 * Don't add the gid_t if it is already in the current group
			 * list. Some UNIXen don't like the same group more than once.
			 */
			int j;

			for (j = 0; j < current_n_groups; j++)
				if (final_groups[j] == new_grp)
					break;
		
			if ( j == current_n_groups) {
				/* Group not already present. */
				final_groups[current_n_groups++] = new_grp;
			}
		} else {
			/* SID didn't map. Copy to the new token to be saved. */
			sid_copy(&new_tok->user_sids[new_tok->num_sids++], &ptok->user_sids[i]);
		}
	}
 
	SAFE_FREE(*pp_groups);
	*pp_groups = final_groups;
	*n_groups = current_n_groups;

	/* Replace the old token with the truncated one. */
	delete_nt_token(&ptok);
	*pptok = new_tok;
}
Example #8
0
static BOOL api_pipe_ntlmssp_verify(pipes_struct *p, RPC_AUTH_NTLMSSP_RESP *ntlmssp_resp)
{
	uchar lm_owf[24];
	uchar nt_owf[128];
	int nt_pw_len;
	int lm_pw_len;
	fstring user_name;
	fstring domain;
	fstring wks;

	NTSTATUS nt_status;

	struct auth_context *auth_context = NULL;
	auth_usersupplied_info *user_info = NULL;
	auth_serversupplied_info *server_info = NULL;

	DEBUG(5,("api_pipe_ntlmssp_verify: checking user details\n"));

	memset(p->user_name, '\0', sizeof(p->user_name));
	memset(p->pipe_user_name, '\0', sizeof(p->pipe_user_name));
	memset(p->domain, '\0', sizeof(p->domain));
	memset(p->wks, '\0', sizeof(p->wks));

	/* Set up for non-authenticated user. */
	delete_nt_token(&p->pipe_user.nt_user_token);
	p->pipe_user.ngroups = 0;
	SAFE_FREE( p->pipe_user.groups);

	/* 
	 * Setup an empty password for a guest user.
	 */

	/*
	 * We always negotiate UNICODE.
	 */

	if (p->ntlmssp_chal_flags & NTLMSSP_NEGOTIATE_UNICODE) {
		rpcstr_pull(user_name, ntlmssp_resp->user, sizeof(fstring), ntlmssp_resp->hdr_usr.str_str_len*2, 0 );
		rpcstr_pull(domain, ntlmssp_resp->domain, sizeof(fstring), ntlmssp_resp->hdr_domain.str_str_len*2, 0);
		rpcstr_pull(wks, ntlmssp_resp->wks, sizeof(fstring), ntlmssp_resp->hdr_wks.str_str_len*2, 0);
	} else {
		pull_ascii_fstring(user_name, ntlmssp_resp->user);
		pull_ascii_fstring(domain, ntlmssp_resp->domain);
		pull_ascii_fstring(wks, ntlmssp_resp->wks);
	}

	DEBUG(5,("user: %s domain: %s wks: %s\n", user_name, domain, wks));

	nt_pw_len = MIN(sizeof(nt_owf), ntlmssp_resp->hdr_nt_resp.str_str_len);
	lm_pw_len = MIN(sizeof(lm_owf), ntlmssp_resp->hdr_lm_resp.str_str_len);

	memcpy(lm_owf, ntlmssp_resp->lm_resp, sizeof(lm_owf));
	memcpy(nt_owf, ntlmssp_resp->nt_resp, nt_pw_len);

#ifdef DEBUG_PASSWORD
	DEBUG(100,("lm, nt owfs, chal\n"));
	dump_data(100, (char *)lm_owf, sizeof(lm_owf));
	dump_data(100, (char *)nt_owf, nt_pw_len);
	dump_data(100, (char *)p->challenge, 8);
#endif

	/*
	 * Allow guest access. Patch from Shirish Kalele <*****@*****.**>.
	 */

	if (*user_name) {

	 	/* 
		 * Do the length checking only if user is not NULL.
		 */

 		if (ntlmssp_resp->hdr_lm_resp.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_nt_resp.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_usr.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_domain.str_str_len == 0)
 			return False;
 		if (ntlmssp_resp->hdr_wks.str_str_len == 0)
 			return False;

	}
	
	make_auth_context_fixed(&auth_context, (uchar*)p->challenge);

	if (!make_user_info_netlogon_network(&user_info, 
					     user_name, domain, wks,
					     lm_owf, lm_pw_len, 
					     nt_owf, nt_pw_len)) {
		DEBUG(0,("make_user_info_netlogon_network failed!  Failing authenticaion.\n"));
		return False;
	}
	
	nt_status = auth_context->check_ntlm_password(auth_context, user_info, &server_info); 
	
	(auth_context->free)(&auth_context);
	free_user_info(&user_info);
	
	p->ntlmssp_auth_validated = NT_STATUS_IS_OK(nt_status);
	
	if (!p->ntlmssp_auth_validated) {
		DEBUG(1,("api_pipe_ntlmssp_verify: User [%s]\\[%s] from machine %s \
failed authentication on named pipe %s.\n", domain, user_name, wks, p->name ));
		free_server_info(&server_info);
		return False;
	}