/* * Turn a DCE name into an LDAP distinguished name. * This needs to be fixed to support DCE CDS style * names. */ static void rpc_ns__ldap_crack_name(unsigned32 entry_name_syntax, unsigned_char_p_t entry_name, unsigned_char_p_t *dn, unsigned32 *status) { switch (entry_name_syntax) { /* /DC=com/DC=padl/DC=nt/CN=RpcServices/CN=foo */ case rpc_c_ns_syntax_x500: { char *tmp; tmp = ldap_dcedn2dn(entry_name); if (tmp == NULL) { *status = rpc_s_invalid_name_syntax; } else { *status = rpc_s_ok; *dn = rpc_stralloc(tmp); } } /* CN=foo,CN=RpcServices,DC=nt,DC=padl,DC=com */ case rpc_c_ns_syntax_ldap: *dn = rpc_stralloc(entry_name); break; /* * /.:/foo or * /.../nt.padl.com/foo */ case rpc_c_ns_syntax_default: case rpc_c_ns_syntax_dce: /* need to do something about cell-relative names */ default: *status = rpc_s_unsupported_name_syntax; break; } }
static void rpc_ns__ldap_lookup_server_element(LDAP *ld, unsigned_char_p_t serverDN, rpc_if_handle_t if_spec, unsigned_char_p_t *dn, unsigned32 *status) { unsigned_char_p_t filter = NULL; unsigned_char_p_t uuid = NULL; rpc_if_id_t if_id; LDAPMessage *msg = NULL, *e; char *_dn; size_t len; rpc_if_inq_id(if_spec, &if_id, status); if (*status != rpc_s_ok) { goto out; } /* Get the interface ID */ uuid_to_string(&if_id.uuid, &uuid, status); if (*status != rpc_s_ok) { goto out; } len = strlen(uuid); len += sizeof("(&(objectClass=rpcServerElement)(rpcNsInterfaceID=,65535.65535))"); RPC_MEM_ALLOC(filter, unsigned_char_p_t, len, RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); sprintf(filter, "(&(objectClass=rpcServerElement)(rpcNsInterfaceID=%s,%hu.%hu))", uuid, if_id.vers_major, if_id.vers_minor); if (ldap_search_s(ld, serverDN, LDAP_SCOPE_ONELEVEL, filter, NULL, 0, &msg) != LDAP_SUCCESS) { *status = rpc_s_not_found; goto out; } e = ldap_first_entry(ld, msg); if (e == NULL) { *status = rpc_s_not_found; goto out; } _dn = ldap_get_dn(ld, e); if (dn == NULL) { *status = rpc_s_not_found; goto out; } *dn = rpc_stralloc(_dn); ldap_memfree(_dn); out: if (filter != NULL) { RPC_MEM_FREE(filter, RPC_C_MEM_NSRESOLUTION); } if (msg != NULL) { ldap_msgfree(msg); } if (uuid != NULL) { rpc_string_free(&uuid, status); } }
INTERNAL void rpc__ntlmauth_bnd_set_auth ( unsigned_char_p_t server_name, rpc_authn_level_t level, rpc_auth_identity_handle_t auth_ident, rpc_authz_protocol_id_t authz_prot, rpc_binding_handle_t binding_h, rpc_auth_info_p_t *infop, unsigned32 *stp ) { unsigned32 st = rpc_s_ok; rpc_ntlmssp_auth_ident_t_p auth_info = NULL; rpc_ntlmauth_info_p_t ntlmauth_info = NULL; gss_name_t gss_server_name = {0}; unsigned char *str_server_name = NULL; gss_buffer_desc username_buf = {0}; gss_name_t gss_user_name = NULL; int gss_rc = 0; OM_uint32 minor_status = 0; gss_OID_set_desc desired_mech; gss_OID_set ret_mech; gss_cred_id_t cred_handle = GSS_C_NO_CREDENTIAL; OM_uint32 time_rec = 0; gss_OID_desc gss_ntlm_oid_desc = {0}; gss_OID_desc gss_cred_opt_password_oid_desc = {0}; gss_buffer_desc auth_buffer = {0}; RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, ("(rpc__gssauth_bnd_set_auth)\n")); rpc_g_ntlmauth_alloc_count++; RPC_MEM_ALLOC(ntlmauth_info, rpc_ntlmauth_info_p_t, sizeof (*ntlmauth_info), RPC_C_MEM_NTLMAUTH_INFO, RPC_C_MEM_WAITOK); memset(ntlmauth_info, 0, sizeof(*ntlmauth_info)); if (authz_prot != rpc_c_authz_name) { st = rpc_s_authn_authz_mismatch; goto poison; } if ((level != rpc_c_authn_level_connect) && (level != rpc_c_authn_level_pkt_integrity) && (level != rpc_c_authn_level_pkt_privacy)) { st = rpc_s_unsupported_authn_level; goto poison; } if (server_name == NULL || auth_ident == NULL) { st = rpc_s_invalid_arg; goto poison; } auth_info = (rpc_ntlmssp_auth_ident_t_p)auth_ident; if (authz_prot == rpc_c_authz_name) { gss_buffer_desc input_name; /* GSS_KRB5_NT_PRINCIPAL_NAME */ gss_OID_desc nt_principal = {10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"}; int gss_rc = 0; OM_uint32 minor_status = 0; if (server_name == NULL) { rpc_mgmt_inq_server_princ_name(binding_h, rpc_c_authn_winnt, &str_server_name, &st); if (st != rpc_s_ok) { goto poison; } } else { str_server_name = rpc_stralloc(server_name); } input_name.value = (void *)str_server_name; input_name.length = strlen((char *)str_server_name); gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &gss_server_name); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__gssauth_bnd_set_auth): import: %s\n", msg)); goto poison; } } gss_ntlm_oid_desc.length = GSS_MECH_NTLM_LEN; gss_ntlm_oid_desc.elements = GSS_MECH_NTLM; gss_cred_opt_password_oid_desc.length = GSS_CRED_OPT_PW_LEN; gss_cred_opt_password_oid_desc.elements = GSS_CRED_OPT_PW; username_buf.value = auth_info->User; username_buf.length = auth_info->UserLength; gss_rc = gss_import_name(&minor_status, &username_buf, GSS_C_NT_USER_NAME, &gss_user_name); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_bnd_set_auth): import: %s\n", msg)); goto poison; } desired_mech.elements = (gss_OID)&gss_ntlm_oid_desc; desired_mech.count = 1; gss_rc = gss_acquire_cred(&minor_status, gss_user_name, 0, &desired_mech, GSS_C_INITIATE, &cred_handle, &ret_mech, &time_rec); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_bnd_set_auth): import: %s\n", msg)); goto poison; } auth_buffer.value = auth_info; auth_buffer.length = sizeof(*auth_info); gss_rc = gssspi_set_cred_option(&minor_status, cred_handle, (gss_OID)&gss_cred_opt_password_oid_desc, &auth_buffer); if (gss_rc != GSS_S_COMPLETE) { char msg[256] = {0}; rpc__ntlmauth_error_map(gss_rc, minor_status, GSS_C_NO_OID, msg, sizeof(msg), &st); RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, ("(rpc__ntlmauth_bnd_set_auth): import: %s\n", msg)); goto poison; } ntlmauth_info->auth_info.server_princ_name = str_server_name; ntlmauth_info->auth_info.authn_level = level; ntlmauth_info->auth_info.authn_protocol = rpc_c_authn_winnt; ntlmauth_info->auth_info.authz_protocol = authz_prot; ntlmauth_info->auth_info.is_server = 0; ntlmauth_info->auth_info.u.auth_identity = auth_ident; ntlmauth_info->auth_info.refcount = 1; ntlmauth_info->gss_server_name = gss_server_name; ntlmauth_info->gss_creds = cred_handle; if (gss_user_name) { gss_release_name(&minor_status, &gss_user_name); } *infop = &ntlmauth_info->auth_info; *stp = st; return; poison: *infop = NULL; *stp = st; return; }
PRIVATE void rpc__ntlmauth_bnd_set_auth ( unsigned_char_p_t server_name, rpc_authn_level_t level, rpc_auth_identity_handle_t auth_ident, rpc_authz_protocol_id_t authz_prot, rpc_binding_handle_t binding_h, rpc_auth_info_p_t *infop, unsigned32 *stp ) { int st; rpc_ntlmauth_info_p_t ntlmauth_info; rpc_g_ntlmauth_alloc_count++; RPC_MEM_ALLOC (ntlmauth_info, rpc_ntlmauth_info_p_t, sizeof (*ntlmauth_info), RPC_C_MEM_UTIL, RPC_C_MEM_WAITOK); if (authz_prot != rpc_c_authz_none) { st = rpc_s_authn_authz_mismatch; goto poison; } if (level != rpc_c_authn_level_none) { st = rpc_s_unsupported_authn_level; goto poison; } /* * If no server principal name was specified, go ask for it. */ if (server_name == NULL) { rpc_mgmt_inq_server_princ_name (binding_h, dce_c_rpc_authn_protocol_krb5, &server_name, stp); if (*stp != rpc_s_ok) return; } else { server_name = rpc_stralloc(server_name); } RPC_DBG_PRINTF(rpc_e_dbg_auth, 1, ( "(rpc__ntlmauth_bnd_set_auth) %x created (now %d active)\n", ntlmauth_info, rpc_g_ntlmauth_alloc_count - rpc_g_ntlmauth_free_count)); memset (ntlmauth_info, 0, sizeof(*ntlmauth_info)); RPC_MUTEX_INIT(ntlmauth_info->lock); ntlmauth_info->auth_info.server_princ_name = server_name; ntlmauth_info->auth_info.authn_level = level; ntlmauth_info->auth_info.authn_protocol = rpc_c_authn_dce_dummy; ntlmauth_info->auth_info.authz_protocol = authz_prot; ntlmauth_info->auth_info.is_server = 0; ntlmauth_info->auth_info.u.auth_identity = auth_ident; ntlmauth_info->auth_info.refcount = 1; *infop = &ntlmauth_info->auth_info; ntlmauth_info->status = rpc_s_ok; *stp = rpc_s_ok; return; poison: *infop = (rpc_auth_info_p_t) &ntlmauth_info->auth_info; ntlmauth_info->status = st; *stp = st; return; }