Beispiel #1
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--;
}
Beispiel #2
0
/*
 *
 * free_server - free a server and possibly its queues also
 *
 *   sinfo - the server_info list head
 *   free_queues_too - flag to free the queues attached to server also
 *
 * returns nothing
 *
 */
void free_server(server_info *sinfo, int free_objs_too)
  {
  if (sinfo == NULL)
    return;

  if (free_objs_too)
    {
    free_queues(sinfo -> queues, 1);
    free_nodes(sinfo -> nodes);
    }

  free_token_list(sinfo -> tokens);

  free_server_info(sinfo);
  }
Beispiel #3
0
void auth_ntlmssp_end(AUTH_NTLMSSP_STATE **auth_ntlmssp_state)
{
	TALLOC_CTX *mem_ctx = (*auth_ntlmssp_state)->mem_ctx;

	if ((*auth_ntlmssp_state)->ntlmssp_state) {
		ntlmssp_end(&(*auth_ntlmssp_state)->ntlmssp_state);
	}
	if ((*auth_ntlmssp_state)->auth_context) {
		((*auth_ntlmssp_state)->auth_context->free)(&(*auth_ntlmssp_state)->auth_context);
	}
	if ((*auth_ntlmssp_state)->server_info) {
		free_server_info(&(*auth_ntlmssp_state)->server_info);
	}
	talloc_destroy(mem_ctx);
	*auth_ntlmssp_state = NULL;
}
Beispiel #4
0
/**
 * COMMAND /disconnect
 *
 * Terminate connection or abort a connection process.
 */
static int cmd_disconnect(int argc, dstring** argv) {
	mutex_lock(&client.network_lock);
	if (client.state == SVCECLIENT_STATE_CONNECTED) {
		free_server_info();
		enet_peer_disconnect(client.client, 0);
		enet_host_destroy(client.host);
		client.client = NULL;
		client.host = NULL;
		client.state = SVCECLIENT_STATE_DISCONNECTED;
		msg_state();
	} else if (client.state == SVCECLIENT_STATE_CONNECTING) {
		enet_peer_disconnect(client.client, 0);
		enet_host_destroy(client.host);
		client.client = NULL;
		client.host = NULL;
		client.state = SVCECLIENT_STATE_DISCONNECTED;
		msg_state();
	} else {
		fprintf(stderr, "Not connected.\n");
	}
	mutex_unlock(&client.network_lock);
	return 0;
}
Beispiel #5
0
// Sends an intialize message to the server
// @param sockfd the socket file descriptor
// @param server the server being sent to
// @param seq the sequence number of the message
// @param file a pointer to the file variable
// @param client a pointer to the client variable
// @param hftpd a pointer to the server information
// @param p a pointer to the filename
// @param count the position in the list of files
static void send_initialize(int sockfd, host *server, int *seq, file_info *file,
                         client_info *client, server_info *hftpd, csv_record *p, int count) {
    
    hftp_control_message *control = (hftp_control_message*)create_control_message(INITIALIZE, *seq, p, client->token, file->file_length);
    
    syslog(LOG_INFO, "Transferring '%s' (%d of %d)", p->filename, count, get_list_length(client->response_list));
    syslog(LOG_DEBUG, "Type: Initialization, Sequence: %d, Filename length: %d", control->sequence, ntohs(control->filename_length));
    
    // Transmit a control request
    if (transmit(sockfd, (message**)&control, server, seq) == -1) {
        
        syslog(LOG_INFO, "Authentication with Hooli file transfer server failed");
        free_file_info(file);
        close(sockfd);
        
        free_server_info(hftpd);
        free_client_info(client);
        
        exit(EXIT_FAILURE);
        
    } //end if
    
} //end send_control
Beispiel #6
0
/**
 * Free client state.
 */
void quit_client_state() {
	int input_error;

	/* free enet structures */
	if (client.client) enet_peer_disconnect(client.client, 0);
	if (client.host) enet_host_destroy(client.host);


	/* get thread status */
	mutex_lock(&client.input_lock);
	input_error = client.input_error;
	mutex_unlock(&client.input_lock);

	/* cancel the input thread if needed */
	if (!input_error) {
		mutex_lock(&client.input_lock);
		thread_cancel(client.input_thread);
		mutex_unlock(&client.input_lock);
	}

	/* join a canceled thread */
	thread_join(client.input_thread);
	/* destroy the input lock */
	mutex_destroy(&client.input_lock);

	mutex_destroy(&client.network_lock);

	/* free other input resources */
	free(client.input_buffer);
	dlist_free(client.input_queue);

	dfree(client.server_host_addr);
	dfree(client.server_host_name);

	free_server_info();
}
Beispiel #7
0
int main(int argc, char* argv[]) {
	dstring* input;
	int input_done;
	int code;
	ENetEvent event;

	if (argc > 1) {
		fprintf(stderr, "svcc doesn't accept any command line arguments, use stdin instead.\n");
		return 1;
	}

	/* initialize enet */
	if (enet_initialize()) {
		fprintf(stderr, "Failed to initialize ENet\n");
		return 1;
	}

	/* initialize client state */
	init_client_state();

	/* init SVC */
	svc_init(send_callback);


	/* main loop */
	input = dnew();
	client.main_done = 0;
	signal(SIGINT, sigint);
	while(!client.main_done) {
		/* enet event handler */
		if (client.state == SVCECLIENT_STATE_CONNECTED) {
			/* handle connection state */

			while (1) {
				mutex_lock(&client.network_lock);
				code = enet_host_service(client.host, &event, 0);
				mutex_unlock(&client.network_lock);
				if (code <= 0) break;

				/* handle event */
				switch(event.type) {
				case ENET_EVENT_TYPE_DISCONNECT:
					/* we got disconnected */
					mutex_lock(&client.network_lock);
					client.state = SVCECLIENT_STATE_DISCONNECTED;
					free_server_info();
					mutex_unlock(&client.network_lock);
					msg_state();
					break;

				case ENET_EVENT_TYPE_RECEIVE:
					/* some data just arrived */
					if (event.channelID == 0) {
						handle_server_msg(event.packet);
					} else if (event.channelID == 1) {
						handle_server_audio(event.packet);
					} else {
						fprintf(stderr, "Received message from server on invalid channel %i.\n", event.channelID);
					}
					mutex_lock(&client.network_lock);
					enet_packet_destroy(event.packet);
					mutex_unlock(&client.network_lock);
					break;

				case ENET_EVENT_TYPE_CONNECT:
					/* no one will connect, ignore the bastard */
				default:
					break;
				}

			}
		} else if (client.state == SVCECLIENT_STATE_CONNECTING) {
			/* handle connecting state */
			mutex_lock(&client.network_lock);
			code = enet_host_service(client.host, &event, 0);
			mutex_unlock(&client.network_lock);

			if (code > 0) {
				if (event.type == ENET_EVENT_TYPE_CONNECT) {
					client.state = SVCECLIENT_STATE_CONNECTED;
					client.server_info = dsdict_new();
					msg_state();
				} else {
					mutex_lock(&client.network_lock);
					client.state = SVCECLIENT_STATE_DISCONNECTED;
					enet_peer_disconnect(client.client, 0);
					client.client = NULL;
					enet_host_destroy(client.host);
					client.host = NULL;
					msg_state();
					mutex_unlock(&client.network_lock);
				}
			}
		} else {
			/* sleep for 8ms */
			usleep(8000);
		}

		/* play with the input queue */
		if (!client.main_done) {
			input_done = 0;
			while (!input_done) {
				/* get next input command */
				mutex_lock(&client.input_lock);
				if (client.input_queue->size) {
					dcpy(input, client.input_queue->front->string);
					dlist_erase(client.input_queue, client.input_queue->front);
				} else {
					input_done = 1;
				}
				mutex_unlock(&client.input_lock);

				/* quit input loop if queue is empty */
				if (input_done) {
					break;
				}

				/* handle commands */
				input_done = client.main_done = handle_input_command(input);
			}
		}

		/* check if input died for some reasons */
		mutex_lock(&client.input_lock);
		if (client.input_error) {
			/* if so, leave main loop */
			client.main_done = 1;
		}
		mutex_unlock(&client.input_lock);

		fflush(stdout);
		fflush(stderr);

		/* sleep for 8ms */
		usleep(8000);
	}

	fprintf(stdout, ":STATE exiting\n");
	dfree(input);

	svc_close();

	quit_client_state();

	enet_deinitialize();

	return 0;
}
Beispiel #8
0
NTSTATUS _net_sam_logon(pipes_struct *p, NET_Q_SAM_LOGON *q_u, NET_R_SAM_LOGON *r_u)
{
	NTSTATUS status = NT_STATUS_OK;
	NET_USER_INFO_3 *usr_info = NULL;
	NET_ID_INFO_CTR *ctr = q_u->sam_id.ctr;
	DOM_CRED srv_cred;
	UNISTR2 *uni_samlogon_user = NULL;
	UNISTR2 *uni_samlogon_domain = NULL;
	UNISTR2 *uni_samlogon_workstation = NULL;
	fstring nt_username, nt_domain, nt_workstation;
	auth_usersupplied_info *user_info = NULL;
	auth_serversupplied_info *server_info = NULL;
	extern userdom_struct current_user_info;
	SAM_ACCOUNT *sampw;
	struct auth_context *auth_context = NULL;
	        
	usr_info = (NET_USER_INFO_3 *)talloc(p->mem_ctx, sizeof(NET_USER_INFO_3));
	if (!usr_info)
		return NT_STATUS_NO_MEMORY;

	ZERO_STRUCTP(usr_info);

 	/* store the user information, if there is any. */
	r_u->user = usr_info;
	r_u->switch_value = 0; /* indicates no info */
	r_u->auth_resp = 1; /* authoritative response */
	r_u->switch_value = 3; /* indicates type of validation user info */
 
	if (!get_valid_user_struct(p->vuid))
		return NT_STATUS_NO_SUCH_USER;


	if ( (lp_server_schannel() == True) && (!p->netsec_auth_validated) ) {
		/* 'server schannel = yes' should enforce use of
		   schannel, the client did offer it in auth2, but
		   obviously did not use it. */
		return NT_STATUS_ACCESS_DENIED;
	}

	/* checks and updates credentials.  creates reply credentials */
	if (!(p->dc.authenticated && deal_with_creds(p->dc.sess_key, &p->dc.clnt_cred, &q_u->sam_id.client.cred, &srv_cred)))
		return NT_STATUS_INVALID_HANDLE;

	memcpy(&p->dc.srv_cred, &p->dc.clnt_cred, sizeof(p->dc.clnt_cred));
    
	r_u->buffer_creds = 1; /* yes, we have valid server credentials */
	memcpy(&r_u->srv_creds, &srv_cred, sizeof(r_u->srv_creds));

	/* find the username */
    
	switch (q_u->sam_id.logon_level) {
	case INTERACTIVE_LOGON_TYPE:
		uni_samlogon_user = &ctr->auth.id1.uni_user_name;
 		uni_samlogon_domain = &ctr->auth.id1.uni_domain_name;

                uni_samlogon_workstation = &ctr->auth.id1.uni_wksta_name;
            
		DEBUG(3,("SAM Logon (Interactive). Domain:[%s].  ", lp_workgroup()));
		break;
	case NET_LOGON_TYPE:
		uni_samlogon_user = &ctr->auth.id2.uni_user_name;
		uni_samlogon_domain = &ctr->auth.id2.uni_domain_name;
		uni_samlogon_workstation = &ctr->auth.id2.uni_wksta_name;
            
		DEBUG(3,("SAM Logon (Network). Domain:[%s].  ", lp_workgroup()));
		break;
	default:
		DEBUG(2,("SAM Logon: unsupported switch value\n"));
		return NT_STATUS_INVALID_INFO_CLASS;
	} /* end switch */

	rpcstr_pull(nt_username,uni_samlogon_user->buffer,sizeof(nt_username),uni_samlogon_user->uni_str_len*2,0);
	rpcstr_pull(nt_domain,uni_samlogon_domain->buffer,sizeof(nt_domain),uni_samlogon_domain->uni_str_len*2,0);
	rpcstr_pull(nt_workstation,uni_samlogon_workstation->buffer,sizeof(nt_workstation),uni_samlogon_workstation->uni_str_len*2,0);

	DEBUG(3,("User:[%s@%s] Requested Domain:[%s]\n", nt_username, 
                 nt_workstation, nt_domain));
   	
	fstrcpy(current_user_info.smb_name, nt_username);
	sub_set_smb_name(nt_username);
     
	DEBUG(5,("Attempting validation level %d for unmapped username %s.\n", q_u->sam_id.ctr->switch_value, nt_username));

	status = NT_STATUS_OK;
	
	switch (ctr->switch_value) {
	case NET_LOGON_TYPE:
	{
		const char *wksname = nt_workstation;
		
		if (!NT_STATUS_IS_OK(status = make_auth_context_fixed(&auth_context, ctr->auth.id2.lm_chal))) {
			return status;
		}

		/* For a network logon, the workstation name comes in with two
		 * backslashes in the front. Strip them if they are there. */

		if (*wksname == '\\') wksname++;
		if (*wksname == '\\') wksname++;

		/* Standard challenge/response authenticaion */
		if (!make_user_info_netlogon_network(&user_info, 
						     nt_username, nt_domain, 
						     wksname,
						     ctr->auth.id2.lm_chal_resp.buffer,
						     ctr->auth.id2.lm_chal_resp.str_str_len,
						     ctr->auth.id2.nt_chal_resp.buffer,
						     ctr->auth.id2.nt_chal_resp.str_str_len)) {
			status = NT_STATUS_NO_MEMORY;
		}	
		break;
	}
	case INTERACTIVE_LOGON_TYPE:
		/* 'Interactive' autheticaion, supplies the password in its
		   MD4 form, encrypted with the session key.  We will
		   convert this to chellange/responce for the auth
		   subsystem to chew on */
	{
		const uint8 *chal;
		
		if (!NT_STATUS_IS_OK(status = make_auth_context_subsystem(&auth_context))) {
			return status;
		}
		
		chal = auth_context->get_ntlm_challenge(auth_context);

		if (!make_user_info_netlogon_interactive(&user_info, 
							 nt_username, nt_domain, 
							 nt_workstation, chal,
							 ctr->auth.id1.lm_owf.data, 
							 ctr->auth.id1.nt_owf.data, 
							 p->dc.sess_key)) {
			status = NT_STATUS_NO_MEMORY;
		}
		break;
	}
	default:
		DEBUG(2,("SAM Logon: unsupported switch value\n"));
		return NT_STATUS_INVALID_INFO_CLASS;
	} /* end switch */
	
	if ( NT_STATUS_IS_OK(status) ) {
		status = auth_context->check_ntlm_password(auth_context, 
			user_info, &server_info);
	}

	(auth_context->free)(&auth_context);	
	free_user_info(&user_info);
	
	DEBUG(5, ("_net_sam_logon: check_password returned status %s\n", 
		  nt_errstr(status)));

	/* Check account and password */
    
	if (!NT_STATUS_IS_OK(status)) {
		free_server_info(&server_info);
		return status;
	}

	if (server_info->guest) {
		/* We don't like guest domain logons... */
		DEBUG(5,("_net_sam_logon: Attempted domain logon as GUEST denied.\n"));
		free_server_info(&server_info);
		return NT_STATUS_LOGON_FAILURE;
	}

	/* This is the point at which, if the login was successful, that
           the SAM Local Security Authority should record that the user is
           logged in to the domain.  */
    
	{
		DOM_GID *gids = NULL;
		const DOM_SID *user_sid = NULL;
		const DOM_SID *group_sid = NULL;
		DOM_SID domain_sid;
		uint32 user_rid, group_rid; 

		int num_gids = 0;
		pstring my_name;
		fstring user_sid_string;
		fstring group_sid_string;
		uchar user_session_key[16];
		uchar lm_session_key[16];
		uchar netlogon_sess_key[16];

		sampw = server_info->sam_account;

		/* set up pointer indicating user/password failed to be found */
		usr_info->ptr_user_info = 0;

		user_sid = pdb_get_user_sid(sampw);
		group_sid = pdb_get_group_sid(sampw);

		sid_copy(&domain_sid, user_sid);
		sid_split_rid(&domain_sid, &user_rid);

		if (!sid_peek_check_rid(&domain_sid, group_sid, &group_rid)) {
			DEBUG(1, ("_net_sam_logon: user %s\\%s has user sid %s\n but group sid %s.\nThe conflicting domain portions are not supported for NETLOGON calls\n", 	    
				  pdb_get_domain(sampw), pdb_get_username(sampw),
				  sid_to_string(user_sid_string, user_sid),
				  sid_to_string(group_sid_string, group_sid)));
			return NT_STATUS_UNSUCCESSFUL;
		}
		
		pstrcpy(my_name, global_myname());

		if (!NT_STATUS_IS_OK(status 
				     = nt_token_to_group_list(p->mem_ctx, 
							      &domain_sid, 
							      server_info->ptok, 
							      &num_gids, 
							      &gids))) {
			return status;
		}

		ZERO_STRUCT(netlogon_sess_key);
		memcpy(netlogon_sess_key, p->dc.sess_key, 8);
		if (server_info->user_session_key.length) {
			memcpy(user_session_key, server_info->user_session_key.data, 
			       MIN(sizeof(user_session_key), server_info->user_session_key.length));
			SamOEMhash(user_session_key, netlogon_sess_key, 16);
		}
		if (server_info->lm_session_key.length) {
			memcpy(lm_session_key, server_info->lm_session_key.data, 
			       MIN(sizeof(lm_session_key), server_info->lm_session_key.length));
			SamOEMhash(lm_session_key, netlogon_sess_key, 16);
		}
		ZERO_STRUCT(netlogon_sess_key);
		
		init_net_user_info3(p->mem_ctx, usr_info, 
				    user_rid,
				    group_rid,   
				    pdb_get_username(sampw),
				    pdb_get_fullname(sampw),
				    pdb_get_homedir(sampw),
				    pdb_get_dir_drive(sampw),
				    pdb_get_logon_script(sampw),
				    pdb_get_profile_path(sampw),
				    pdb_get_logon_time(sampw),
				    get_time_t_max(),
				    get_time_t_max(),
				    pdb_get_pass_last_set_time(sampw),
				    pdb_get_pass_can_change_time(sampw),
				    pdb_get_pass_must_change_time(sampw),
				    
				    0, /* logon_count */
				    0, /* bad_pw_count */
				    num_gids,    /* uint32 num_groups */
				    gids    , /* DOM_GID *gids */
				    0x20    , /* uint32 user_flgs (?) */
				    server_info->user_session_key.length ? user_session_key : NULL,
				    server_info->lm_session_key.length ? lm_session_key : NULL,
				    my_name     , /* char *logon_srv */
				    pdb_get_domain(sampw),
				    &domain_sid,     /* DOM_SID *dom_sid */  
				    /* Should be users domain sid, not servers - for trusted domains */
				  
				    NULL); /* char *other_sids */
		ZERO_STRUCT(user_session_key);
		ZERO_STRUCT(lm_session_key);
	}
	free_server_info(&server_info);
	return status;
}
Beispiel #9
0
int register_vuid(auth_serversupplied_info *server_info, DATA_BLOB session_key, DATA_BLOB response_blob, const char *smb_name)
{
	user_struct *vuser = NULL;

	/* Ensure no vuid gets registered in share level security. */
	if(lp_security() == SEC_SHARE) {
		data_blob_free(&session_key);
		return UID_FIELD_INVALID;
	}

	/* Limit allowed vuids to 16bits - VUID_OFFSET. */
	if (num_validated_vuids >= 0xFFFF-VUID_OFFSET) {
		data_blob_free(&session_key);
		return UID_FIELD_INVALID;
	}

	if((vuser = SMB_MALLOC_P(user_struct)) == NULL) {
		DEBUG(0,("Failed to malloc users struct!\n"));
		data_blob_free(&session_key);
		return UID_FIELD_INVALID;
	}

	ZERO_STRUCTP(vuser);

	/* Allocate a free vuid. Yes this is a linear search... :-) */
	while( get_valid_user_struct(next_vuid) != NULL ) {
		next_vuid++;
		/* Check for vuid wrap. */
		if (next_vuid == UID_FIELD_INVALID)
			next_vuid = VUID_OFFSET;
	}

	DEBUG(10,("register_vuid: allocated vuid = %u\n", (unsigned int)next_vuid ));

	vuser->vuid = next_vuid;

	/* the next functions should be done by a SID mapping system (SMS) as
	 * the new real sam db won't have reference to unix uids or gids
	 */
	
	vuser->uid = server_info->uid;
	vuser->gid = server_info->gid;
	
	vuser->n_groups = server_info->n_groups;
	if (vuser->n_groups) {
		if (!(vuser->groups = memdup(server_info->groups, sizeof(gid_t) * vuser->n_groups))) {
			DEBUG(0,("register_vuid: failed to memdup vuser->groups\n"));
			data_blob_free(&session_key);
			free(vuser);
			free_server_info(&server_info);
			return UID_FIELD_INVALID;
		}
	}

	vuser->guest = server_info->guest;
	fstrcpy(vuser->user.unix_name, server_info->unix_name); 

	/* This is a potentially untrusted username */
	alpha_strcpy(vuser->user.smb_name, smb_name, ". _-$", sizeof(vuser->user.smb_name));

	fstrcpy(vuser->user.domain, pdb_get_domain(server_info->sam_account));
	fstrcpy(vuser->user.full_name, pdb_get_fullname(server_info->sam_account));

	{
		/* Keep the homedir handy */
		const char *homedir = pdb_get_homedir(server_info->sam_account);
		const char *logon_script = pdb_get_logon_script(server_info->sam_account);

		if (!IS_SAM_DEFAULT(server_info->sam_account, PDB_UNIXHOMEDIR)) {
			const char *unix_homedir = pdb_get_unix_homedir(server_info->sam_account);
			if (unix_homedir) {
				vuser->unix_homedir = smb_xstrdup(unix_homedir);
			}
		} else {
			struct passwd *passwd = getpwnam_alloc(vuser->user.unix_name);
			if (passwd) {
				vuser->unix_homedir = smb_xstrdup(passwd->pw_dir);
				passwd_free(&passwd);
			}
		}
		
		if (homedir) {
			vuser->homedir = smb_xstrdup(homedir);
		}
		if (logon_script) {
			vuser->logon_script = smb_xstrdup(logon_script);
		}
	}

	vuser->session_key = session_key;

	DEBUG(10,("register_vuid: (%u,%u) %s %s %s guest=%d\n", 
		  (unsigned int)vuser->uid, 
		  (unsigned int)vuser->gid,
		  vuser->user.unix_name, vuser->user.smb_name, vuser->user.domain, vuser->guest ));

	DEBUG(3, ("User name: %s\tReal name: %s\n",vuser->user.unix_name,vuser->user.full_name));	

 	if (server_info->ptok) {
		vuser->nt_user_token = dup_nt_token(server_info->ptok);
	} else {
		DEBUG(1, ("server_info does not contain a user_token - cannot continue\n"));
		free_server_info(&server_info);
		data_blob_free(&session_key);
		SAFE_FREE(vuser->homedir);
		SAFE_FREE(vuser->unix_homedir);
		SAFE_FREE(vuser->logon_script);

		SAFE_FREE(vuser);
		return UID_FIELD_INVALID;
	}

	/* use this to keep tabs on all our info from the authentication */
	vuser->server_info = server_info;

	DEBUG(3,("UNIX uid %d is UNIX user %s, and will be vuid %u\n",(int)vuser->uid,vuser->user.unix_name, vuser->vuid));

	next_vuid++;
	num_validated_vuids++;

	DLIST_ADD(validated_users, vuser);

	if (!session_claim(vuser)) {
		DEBUG(1,("Failed to claim session for vuid=%d\n", vuser->vuid));
		invalidate_vuid(vuser->vuid);
		return -1;
	}

	/* Register a home dir service for this user iff
	
	   (a) This is not a guest connection,
	   (b) we have a home directory defined 
	   (c) there s not an existing static share by that name
	   
	   If a share exists by this name (autoloaded or not) reuse it . */

	vuser->homes_snum = -1;

	if ( (!vuser->guest) && vuser->unix_homedir && *(vuser->unix_homedir)) 
	{
		int servicenumber = lp_servicenumber(vuser->user.unix_name);

		if ( servicenumber == -1 ) {
			DEBUG(3, ("Adding homes service for user '%s' using home directory: '%s'\n", 
				vuser->user.unix_name, vuser->unix_homedir));
			vuser->homes_snum = add_home_service(vuser->user.unix_name, 
						vuser->user.unix_name, vuser->unix_homedir);
		} else {
			DEBUG(3, ("Using static (or previously created) service for user '%s'; path = '%s'\n", 
				vuser->user.unix_name, lp_pathname(servicenumber) ));
			vuser->homes_snum = servicenumber;
		}
	} 
	
	if (srv_is_signing_negotiated() && !vuser->guest && !srv_signing_started()) {
		/* Try and turn on server signing on the first non-guest sessionsetup. */
		srv_set_signing(vuser->session_key, response_blob);
	}
	
	/* fill in the current_user_info struct */
	set_current_user_info( &vuser->user );


	return vuser->vuid;
}