예제 #1
0
/*
 * Build the SPNEGO "hint" token based on the
 * configured authentication mechanisms.
 * (NTLMSSP, and maybe Kerberos)
 */
void
smbd_get_authconf(smb_kmod_cfg_t *kcfg)
{
	SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
	uchar_t *pBuf = kcfg->skc_negtok;
	uint32_t *pBufLen = &kcfg->skc_negtok_len;
	ulong_t tLen = sizeof (kcfg->skc_negtok);
	int rc;

	rc = spnegoCreateNegTokenHint(MechTypeList, MechTypeCnt,
	    (uchar_t *)IgnoreSPN, &hSpnegoToken);
	if (rc != SPNEGO_E_SUCCESS) {
		syslog(LOG_DEBUG, "smb_config_get_negtok: "
		    "spnegoCreateNegTokenHint, rc=%d", rc);
		*pBufLen = 0;
		return;
	}
	rc = spnegoTokenGetBinary(hSpnegoToken, pBuf, &tLen);
	if (rc != SPNEGO_E_SUCCESS) {
		syslog(LOG_DEBUG, "smb_config_get_negtok: "
		    "spnegoTokenGetBinary, rc=%d", rc);
		*pBufLen = 0;
	} else {
		*pBufLen = (uint32_t)tLen;
	}
	spnegoFreeData(hSpnegoToken);
}
예제 #2
0
void
smbd_authctx_destroy(authsvc_context_t *ctx)
{
	if (ctx->ctx_socket != -1) {
		(void) close(ctx->ctx_socket);
		ctx->ctx_socket = -1;
	}

	if (ctx->ctx_token != NULL)
		smb_token_destroy(ctx->ctx_token);

	if (ctx->ctx_itoken != NULL)
		spnegoFreeData(ctx->ctx_itoken);
	if (ctx->ctx_otoken != NULL)
		spnegoFreeData(ctx->ctx_otoken);

	free(ctx->ctx_irawbuf);
	free(ctx->ctx_orawbuf);
	free(ctx->ctx_ibodybuf);
	free(ctx->ctx_obodybuf);

	free(ctx);
}
예제 #3
0
/*
 * Handle a security blob we've received from the client.
 * Incoming type: LSA_MTYPE_ESNEXT
 * Outgoing types: LSA_MTYPE_ES_CONT, LSA_MTYPE_ES_DONE,
 *   LSA_MTYPE_ERROR
 */
static int
smbd_authsvc_esnext(authsvc_context_t *ctx)
{
	int rc;

	/*
	 * Make sure LSA_MTYPE_ESFIRST was handled
	 * previously, so we have a work function.
	 */
	if (ctx->ctx_mh_work == NULL)
		return (NT_STATUS_INVALID_PARAMETER);

	if (ctx->ctx_mech_oid == special_mech_raw_NTLMSSP) {
		rc = smbd_raw_ntlmssp_esnext(ctx);
		return (rc);
	}

	/*
	 * Cleanup state from previous calls.
	 */
	if (ctx->ctx_itoken != NULL) {
		spnegoFreeData(ctx->ctx_itoken);
		ctx->ctx_itoken = NULL;
	}

	/*
	 * Parse the SPNEGO token, check its type.
	 */
	rc = spnegoInitFromBinary(ctx->ctx_irawbuf,
	    ctx->ctx_irawlen, &ctx->ctx_itoken);
	if (rc != 0)
		return (NT_STATUS_INVALID_PARAMETER);

	rc = spnegoGetTokenType(ctx->ctx_itoken, &ctx->ctx_itoktype);
	if (rc != 0)
		return (NT_STATUS_INVALID_PARAMETER);

	if (ctx->ctx_itoktype != SPNEGO_TOKEN_TARG)
		return (NT_STATUS_INVALID_PARAMETER);

	rc = smbd_authsvc_escmn(ctx);
	return (rc);
}
예제 #4
0
/*
 * Build the SPNEGO "hint" token based on the
 * configured authentication mechanisms.
 * (NTLMSSP, and maybe Kerberos)
 */
void
smbd_get_authconf(smb_kmod_cfg_t *kcfg)
{
	SPNEGO_MECH_OID *mechList = MechTypeList;
	int mechCnt = MechTypeCnt;
	SPNEGO_TOKEN_HANDLE hSpnegoToken = NULL;
	uchar_t *pBuf = kcfg->skc_negtok;
	uint32_t *pBufLen = &kcfg->skc_negtok_len;
	ulong_t tLen = sizeof (kcfg->skc_negtok);
	int rc;

	/*
	 * In workgroup mode, skip Kerberos.
	 */
	if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) {
		mechList += MECH_OID_IDX_NTLMSSP;
		mechCnt  -= MECH_OID_IDX_NTLMSSP;
	}

	rc = spnegoCreateNegTokenHint(mechList, mechCnt,
	    (uchar_t *)IgnoreSPN, &hSpnegoToken);
	if (rc != SPNEGO_E_SUCCESS) {
		syslog(LOG_DEBUG, "smb_config_get_negtok: "
		    "spnegoCreateNegTokenHint, rc=%d", rc);
		*pBufLen = 0;
		return;
	}
	rc = spnegoTokenGetBinary(hSpnegoToken, pBuf, &tLen);
	if (rc != SPNEGO_E_SUCCESS) {
		syslog(LOG_DEBUG, "smb_config_get_negtok: "
		    "spnegoTokenGetBinary, rc=%d", rc);
		*pBufLen = 0;
	} else {
		*pBufLen = (uint32_t)tLen;
	}
	spnegoFreeData(hSpnegoToken);
}
예제 #5
0
static int
smbd_authsvc_escmn(authsvc_context_t *ctx)
{
	SPNEGO_MECH_OID oid;
	ulong_t toklen;
	int rc;

	/*
	 * Cleanup state from previous calls.
	 */
	if (ctx->ctx_otoken != NULL) {
		spnegoFreeData(ctx->ctx_otoken);
		ctx->ctx_otoken = NULL;
	}

	/*
	 * Extract the payload (mech token).
	 */
	toklen = ctx->ctx_ibodylen;
	rc = spnegoGetMechToken(ctx->ctx_itoken,
	    ctx->ctx_ibodybuf, &toklen);
	switch (rc) {
	case SPNEGO_E_SUCCESS:
		break;
	case SPNEGO_E_ELEMENT_UNAVAILABLE:
		toklen = 0;
		break;
	case SPNEGO_E_BUFFER_TOO_SMALL:
		return (NT_STATUS_BUFFER_TOO_SMALL);
	default:
		return (NT_STATUS_INTERNAL_ERROR);
	}
	ctx->ctx_ibodylen = toklen;

	/*
	 * Now that we have the incoming "body" (mech. token),
	 * call the back-end mech-specific work function to
	 * create the outgoing "body" (mech. token).
	 *
	 * The worker must fill in:  ctx->ctx_negresult,
	 * and: ctx->ctx_obodylen, but ctx->ctx_obodybuf
	 * is optional, and is typically NULL after the
	 * final message of an auth sequence, where
	 * negresult == spnego_negresult_complete.
	 */
	rc = ctx->ctx_mh_work(ctx);
	if (rc != 0)
		return (rc);

	/*
	 * Wrap the outgoing body in a negTokenTarg SPNEGO token.
	 * The selected mech. OID is returned only when the
	 * incoming token was of type SPNEGO_TOKEN_INIT.
	 */
	if (ctx->ctx_itoktype == SPNEGO_TOKEN_INIT) {
		/* tell the client the selected mech. */
		oid = ctx->ctx_mech_oid;
	} else {
		/* Ommit the "supported mech." field. */
		oid = spnego_mech_oid_NotUsed;
	}

	/*
	 * Determine the spnego "negresult" from the
	 * reply message type (from the work func).
	 */
	switch (ctx->ctx_orawtype) {
	case LSA_MTYPE_ERROR:
		ctx->ctx_negresult = spnego_negresult_rejected;
		break;
	case LSA_MTYPE_ES_DONE:
		ctx->ctx_negresult = spnego_negresult_success;
		break;
	case LSA_MTYPE_ES_CONT:
		ctx->ctx_negresult = spnego_negresult_incomplete;
		break;
	default:
		return (-1);
	}

	rc = spnegoCreateNegTokenTarg(
	    oid,
	    ctx->ctx_negresult,
	    ctx->ctx_obodybuf, /* may be NULL */
	    ctx->ctx_obodylen,
	    NULL, 0,
	    &ctx->ctx_otoken);

	/*
	 * Convert the SPNEGO token into binary form,
	 * writing it to the output buffer.
	 */
	toklen = smbd_authsvc_bufsize;
	rc = spnegoTokenGetBinary(ctx->ctx_otoken,
	    (uchar_t *)ctx->ctx_orawbuf, &toklen);
	if (rc)
		rc = NT_STATUS_INTERNAL_ERROR;
	ctx->ctx_orawlen = (uint_t)toklen;

	return (rc);
}