Exemple #1
0
BOOL afs_login(connection_struct *conn)
{
	DATA_BLOB ticket;
	pstring afs_username;
	char *cell;
	BOOL result;
	char *ticket_str;
	DOM_SID user_sid;

	struct ClearToken ct;

	pstrcpy(afs_username, lp_afs_username_map());
	standard_sub_conn(conn, afs_username, sizeof(afs_username));

	if (NT_STATUS_IS_OK(uid_to_sid(&user_sid, conn->uid)))
		pstring_sub(afs_username, "%s", sid_string_static(&user_sid));

	/* The pts command always generates completely lower-case user
	 * names. */
	strlower_m(afs_username);

	cell = strchr(afs_username, '@');

	if (cell == NULL) {
		DEBUG(1, ("AFS username doesn't contain a @, "
			  "could not find cell\n"));
		return False;
	}

	*cell = '\0';
	cell += 1;

	DEBUG(10, ("Trying to log into AFS for user %s@%s\n", 
		   afs_username, cell));

	if (!afs_createtoken(afs_username, cell, &ticket, &ct))
		return False;

	/* For which Unix-UID do we want to set the token? */
	ct.ViceId = getuid();

	ticket_str = afs_encode_token(cell, ticket, &ct);

	result = afs_settoken_str(ticket_str);

	SAFE_FREE(ticket_str);

	data_blob_free(&ticket);

	return result;
}
Exemple #2
0
enum winbindd_result winbindd_pam_auth(struct winbindd_cli_state *state) 
{
	NTSTATUS result;
	fstring name_domain, name_user;
	unsigned char trust_passwd[16];
	time_t last_change_time;
	uint32 sec_channel_type;
        NET_USER_INFO_3 info3;
        struct cli_state *cli = NULL;
	uchar chal[8];
	TALLOC_CTX *mem_ctx = NULL;
	DATA_BLOB lm_resp;
	DATA_BLOB nt_resp;
	DOM_CRED ret_creds;
	int attempts = 0;
	unsigned char local_lm_response[24];
	unsigned char local_nt_response[24];
	struct winbindd_domain *contact_domain;
	BOOL retry;

	/* Ensure null termination */
	state->request.data.auth.user[sizeof(state->request.data.auth.user)-1]='\0';

	/* Ensure null termination */
	state->request.data.auth.pass[sizeof(state->request.data.auth.pass)-1]='\0';

	DEBUG(3, ("[%5lu]: pam auth %s\n", (unsigned long)state->pid,
		  state->request.data.auth.user));

	if (!(mem_ctx = talloc_init("winbind pam auth for %s", state->request.data.auth.user))) {
		DEBUG(0, ("winbindd_pam_auth: could not talloc_init()!\n"));
		result = NT_STATUS_NO_MEMORY;
		goto done;
	}

	/* Parse domain and username */
	
	parse_domain_user(state->request.data.auth.user, name_domain, name_user);

	/* do password magic */
	
	generate_random_buffer(chal, 8);
	SMBencrypt(state->request.data.auth.pass, chal, local_lm_response);
		
	SMBNTencrypt(state->request.data.auth.pass, chal, local_nt_response);

	lm_resp = data_blob_talloc(mem_ctx, local_lm_response, sizeof(local_lm_response));
	nt_resp = data_blob_talloc(mem_ctx, local_nt_response, sizeof(local_nt_response));
	
	/* what domain should we contact? */
	
	if ( IS_DC ) {
		if (!(contact_domain = find_domain_from_name(name_domain))) {
			DEBUG(3, ("Authentication for domain for [%s] -> [%s]\\[%s] failed as %s is not a trusted domain\n", 
				  state->request.data.auth.user, name_domain, name_user, name_domain)); 
			result = NT_STATUS_NO_SUCH_USER;
			goto done;
		}
		
	} else {
		if (is_myname(name_domain)) {
			DEBUG(3, ("Authentication for domain %s (local domain to this server) not supported at this stage\n", name_domain));
			result =  NT_STATUS_NO_SUCH_USER;
			goto done;
		}

		if (!(contact_domain = find_our_domain())) {
			DEBUG(1, ("Authentication for [%s] -> [%s]\\[%s] in our domain failed - we can't find our domain!\n", 
				  state->request.data.auth.user, name_domain, name_user)); 
			result = NT_STATUS_NO_SUCH_USER;
			goto done;
		}
	}

	if ( !get_trust_pw(contact_domain->name, trust_passwd, &last_change_time, &sec_channel_type) ) {
		result = NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
		goto done;
	}

	/* check authentication loop */

	do {
		ZERO_STRUCT(info3);
		ZERO_STRUCT(ret_creds);
		retry = False;
	
		/* Don't shut this down - it belongs to the connection cache code */
		result = cm_get_netlogon_cli(contact_domain, trust_passwd, 
					     sec_channel_type, False, &cli);

		if (!NT_STATUS_IS_OK(result)) {
			DEBUG(3, ("could not open handle to NETLOGON pipe\n"));
			goto done;
		}

		result = cli_netlogon_sam_network_logon(cli, mem_ctx,
							&ret_creds,
							name_user, name_domain, 
							global_myname(), chal, 
							lm_resp, nt_resp,
							&info3);
		attempts += 1;
		
		/* We have to try a second time as cm_get_netlogon_cli
		   might not yet have noticed that the DC has killed
		   our connection. */

		if ( cli->fd == -1 ) {
			retry = True;
			continue;
		} 
		
		/* if we get access denied, a possible cuase was that we had and open
		   connection to the DC, but someone changed our machine account password
		   out from underneath us using 'net rpc changetrustpw' */
		   
		if ( NT_STATUS_V(result) == NT_STATUS_V(NT_STATUS_ACCESS_DENIED) ) {
			DEBUG(3,("winbindd_pam_auth: sam_logon returned ACCESS_DENIED.  Maybe the trust account "
				"password was changed and we didn't know it.  Killing connections to domain %s\n",
				name_domain));
			winbindd_cm_flush();
			retry = True;
			cli = NULL;
		} 
		
	} while ( (attempts < 2) && retry );

        if (cli != NULL) {
		/* We might have come out of the loop above with cli == NULL,
		   so don't dereference that. */
		clnt_deal_with_creds(cli->sess_key, &(cli->clnt_cred), &ret_creds);
	}
	
	if (NT_STATUS_IS_OK(result)) {
		netsamlogon_cache_store( cli->mem_ctx, &info3 );
		wcache_invalidate_samlogon(find_domain_from_name(name_domain), &info3);

		/* Check if the user is in the right group */

		if (!NT_STATUS_IS_OK(result = check_info3_in_group(mem_ctx, &info3, state->request.data.auth.required_membership_sid))) {
			DEBUG(3, ("User %s is not in the required group (%s), so plaintext authentication is rejected\n",
				  state->request.data.auth.user, 
				  state->request.data.auth.required_membership_sid));
		}
	}

done:
	/* give us a more useful (more correct?) error code */
	if ((NT_STATUS_EQUAL(result, NT_STATUS_DOMAIN_CONTROLLER_NOT_FOUND) || (NT_STATUS_EQUAL(result, NT_STATUS_UNSUCCESSFUL)))) {
		result = NT_STATUS_NO_LOGON_SERVERS;
	}
	
	state->response.data.auth.nt_status = NT_STATUS_V(result);
	fstrcpy(state->response.data.auth.nt_status_string, nt_errstr(result));

	/* we might have given a more useful error above */
	if (!*state->response.data.auth.error_string) 
		fstrcpy(state->response.data.auth.error_string, get_friendly_nt_error_msg(result));
	state->response.data.auth.pam_error = nt_status_to_pam(result);

	DEBUG(NT_STATUS_IS_OK(result) ? 5 : 2, ("Plain-text authentication for user %s returned %s (PAM: %d)\n", 
	      state->request.data.auth.user, 
	      state->response.data.auth.nt_status_string,
	      state->response.data.auth.pam_error));	      

	if ( NT_STATUS_IS_OK(result) &&
	     (state->request.flags & WBFLAG_PAM_AFS_TOKEN) ) {

		char *afsname = strdup(lp_afs_username_map());
		char *cell;

		if (afsname == NULL) goto no_token;

		afsname = realloc_string_sub(afsname, "%D", name_domain);
		afsname = realloc_string_sub(afsname, "%u", name_user);
		afsname = realloc_string_sub(afsname, "%U", name_user);

		if (afsname == NULL) goto no_token;

		strlower_m(afsname);

		cell = strchr(afsname, '@');

		if (cell == NULL) goto no_token;

		*cell = '\0';
		cell += 1;

		/* Append an AFS token string */
		state->response.extra_data =
			afs_createtoken_str(afsname, cell);

		if (state->response.extra_data != NULL)
			state->response.length +=
				strlen(state->response.extra_data)+1;

	no_token:
		SAFE_FREE(afsname);
	}
		
	if (mem_ctx) 
		talloc_destroy(mem_ctx);
	
	return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR;
}
Exemple #3
0
bool afs_login(connection_struct *conn)
{
    DATA_BLOB ticket;
    char *afs_username = NULL;
    char *cell = NULL;
    bool result;
    char *ticket_str = NULL;
    const struct dom_sid *user_sid;
    TALLOC_CTX *ctx = talloc_tos();

    struct ClearToken ct;

    afs_username = talloc_strdup(ctx,
                                 lp_afs_username_map());
    if (!afs_username) {
        return false;
    }

    afs_username = talloc_sub_advanced(ctx,
                                       lp_servicename(SNUM(conn)),
                                       conn->session_info->unix_info->unix_name,
                                       conn->connectpath,
                                       conn->session_info->unix_token->gid,
                                       conn->session_info->unix_info->sanitized_username,
                                       conn->session_info->info->domain_name,
                                       afs_username);
    if (!afs_username) {
        return false;
    }

    user_sid = &conn->session_info->security_token->sids[0];
    afs_username = talloc_string_sub(talloc_tos(),
                                     afs_username,
                                     "%s",
                                     sid_string_tos(user_sid));
    if (!afs_username) {
        return false;
    }

    /* The pts command always generates completely lower-case user
     * names. */
    strlower_m(afs_username);

    cell = strchr(afs_username, '@');

    if (cell == NULL) {
        DEBUG(1, ("AFS username doesn't contain a @, "
                  "could not find cell\n"));
        return false;
    }

    *cell = '\0';
    cell += 1;

    DEBUG(10, ("Trying to log into AFS for user %s@%s\n",
               afs_username, cell));

    if (!afs_createtoken(afs_username, cell, &ticket, &ct))
        return false;

    /* For which Unix-UID do we want to set the token? */
    ct.ViceId = getuid();

    ticket_str = afs_encode_token(cell, ticket, &ct);

    result = afs_settoken_str(ticket_str);

    SAFE_FREE(ticket_str);

    data_blob_free(&ticket);

    return result;
}
Exemple #4
0
BOOL afs_login(connection_struct *conn)
{
	DATA_BLOB ticket;
	pstring afs_username;
	char *cell;
	BOOL result;

	struct ClearToken ct;

	pstrcpy(afs_username, lp_afs_username_map());
	standard_sub_conn(conn, afs_username, sizeof(afs_username));

	/* The pts command always generates completely lower-case user
	 * names. */
	strlower_m(afs_username);

	cell = strchr(afs_username, '@');

	if (cell == NULL) {
		DEBUG(1, ("AFS username doesn't contain a @, "
			  "could not find cell\n"));
		return False;
	}

	*cell = '\0';
	cell += 1;

	DEBUG(10, ("Trying to log into AFS for user %s@%s\n", 
		   afs_username, cell));

	if (!afs_createtoken(afs_username, cell, &ticket, &ct))
		return False;

	/* For which Unix-UID do we want to set the token? */
	ct.ViceId = getuid();

	{
		char *str, *new_cell;
		DATA_BLOB test_ticket;
		struct ClearToken test_ct;

		hex_encode(ct.HandShakeKey, sizeof(ct.HandShakeKey), &str);
		DEBUG(10, ("Key: %s\n", str));
		free(str);

		str = afs_encode_token(cell, ticket, &ct);

		if (!afs_decode_token(str, &new_cell, &test_ticket,
				      &test_ct)) {
			DEBUG(0, ("Could not decode token"));
			goto decode_failed;
		}

		if (strcmp(cell, new_cell) != 0) {
			DEBUG(0, ("cell changed\n"));
		}

		if ((ticket.length != test_ticket.length) ||
		    (memcmp(ticket.data, test_ticket.data,
			    ticket.length) != 0)) {
			DEBUG(0, ("Ticket changed\n"));
		}

		if (memcmp(&ct, &test_ct, sizeof(ct)) != 0) {
			DEBUG(0, ("ClearToken changed\n"));
		}

		data_blob_free(&test_ticket);

	decode_failed:
		SAFE_FREE(str);
		SAFE_FREE(new_cell);
	}

	result = afs_settoken(cell, &ct, ticket);

	data_blob_free(&ticket);

	return result;
}